Angular 6 SPA로 JWT 인증을 수행하는 방법
게시 됨: 2022-03-11오늘 우리는 JSON 웹 토큰(JWT) 인증을 Angular 6(이상) 단일 페이지 애플리케이션(SPA)에 통합하는 것이 얼마나 쉬운지 살펴보겠습니다. 약간의 배경부터 시작하겠습니다.
JSON 웹 토큰이란 무엇이며 왜 사용합니까?
여기서 가장 쉽고 간결한 대답은 편리하고 컴팩트하며 안전하다는 것입니다. 이러한 주장을 자세히 살펴보겠습니다.
- 편리함 : 로그인 후 백엔드 인증을 위해 JWT를 사용하려면 하나의 HTTP 헤더를 설정해야 합니다. 이 작업은 나중에 살펴보겠지만 기능이나 하위 분류를 통해 쉽게 자동화할 수 있습니다.
- 압축 : 토큰은 몇 개의 헤더 필드와 필요한 경우 페이로드를 포함하는 단순히 base64로 인코딩된 문자열입니다. 전체 JWT는 서명된 경우에도 일반적으로 200바이트 미만입니다.
- 보안 : 필수는 아니지만 JWT의 뛰어난 보안 기능은 RSA 공개/개인 키 쌍 암호화 또는 공유 비밀을 사용하는 HMAC 암호화를 사용하여 토큰에 서명할 수 있다는 것입니다. 이것은 토큰의 출처와 유효성을 보장합니다.
이 모든 것이 요약되면 데이터 구조를 구문 분석하거나 자체 암호화를 구현할 필요 없이 사용자를 인증하는 안전하고 효율적인 방법이 있다는 것입니다.
응용 이론
따라서 약간의 배경 지식을 가지고 이제 이것이 실제 응용 프로그램에서 어떻게 작동하는지 자세히 알아볼 수 있습니다. 이 예에서는 API를 호스팅하는 Node.js 서버가 있고 Angular 6을 사용하여 SPA 할 일 목록을 개발 중이라고 가정하겠습니다. 이 API 구조로 작업해 보겠습니다.
-
/auth
→POST
(JWT를 인증하고 다시 받기 위해 사용자 이름과 비밀번호 게시) -
/todos
→GET
(사용자의 할일 목록 항목 목록 반환) -
/todos/{id}
→GET
(특정 할일 목록 항목 반환) -
/users
→GET
(사용자 목록 반환)
이 간단한 응용 프로그램을 만드는 과정을 곧 살펴보겠지만 지금은 이론상 상호 작용에 집중하겠습니다. 사용자가 사용자 이름과 비밀번호를 입력할 수 있는 간단한 로그인 페이지가 있습니다. 양식이 제출되면 해당 정보를 /auth
엔드포인트로 보냅니다. 그런 다음 노드 서버는 적절한 방식(데이터베이스 조회, 다른 웹 서비스 쿼리 등)으로 사용자를 인증할 수 있지만 궁극적으로 엔드포인트는 JWT를 반환해야 합니다.
이 예의 JWT에는 몇 가지 예약된 클레임 과 일부 개인 클레임 이 포함됩니다. 예약된 클레임은 단순히 인증에 일반적으로 사용되는 JWT 권장 키-값 쌍인 반면 비공개 클레임은 앱에만 적용할 수 있는 키-값 쌍입니다.
유보된 클레임
-
iss
: 이 토큰의 발행자. 일반적으로 서버의 FQDN이지만 클라이언트 응용 프로그램이 예상하는 한 무엇이든 될 수 있습니다. -
exp
: 이 토큰의 만료 날짜 및 시간입니다. 1970년 1월 1일 자정(GMT(Unix 시간)) 이후의 초 단위입니다. -
nbf
: 타임스탬프 이전에는 유효하지 않습니다. 자주 사용되지는 않지만 유효 기간에 대한 하한을 제공합니다.exp
와 같은 형식입니다.
개인 청구
-
uid
: 로그인한 사용자의 사용자 ID입니다. -
role
: 로그인한 사용자에게 할당된 역할입니다.
우리 정보는 공유 키 todo-app-super-shared-secret
와 함께 HMAC를 사용하여 base64로 인코딩되고 서명됩니다. 다음은 JWT가 어떻게 보이는지 보여주는 예입니다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b2RvYXBpIiwibmJmIjoxNDk4MTE3NjQyLCJleHAiOjE0OTgxMjEyNDIsInVpZCI6MSwicm9sZSI6ImFkbWluIn0.ZDz_1vcIlnZz64nSM28yA1s-4c_iw3Z2ZtP-SgcYRPQ
이 문자열은 유효한 로그인이 있는지 확인하고, 어떤 사용자가 연결되어 있는지, 사용자에게 어떤 역할이 있는지 확인하는 데 필요한 전부입니다.
대부분의 라이브러리와 애플리케이션은 쉽게 검색할 수 있도록 이 JWT를 localStorage
또는 sessionStorage
에 저장하지만 이는 일반적인 관행일 뿐입니다. 향후 API 호출을 위해 제공할 수 있는 한 토큰으로 수행하는 작업은 사용자에게 달려 있습니다.
이제 SPA가 보호된 API 엔드포인트를 호출하려고 할 때마다 Authorization
HTTP 헤더의 토큰을 함께 보내면 됩니다.
Authorization: Bearer {JWT Token}
참고 : 다시 한 번, 이것은 단순히 일반적인 관행입니다. JWT는 서버에 자신을 보내는 특정 방법을 규정하지 않습니다. URL에 추가하거나 쿠키로 보낼 수도 있습니다.
서버가 JWT를 수신하면 이를 디코딩하고 HMAC 공유 비밀을 사용하여 일관성을 보장하고 exp
및 nbf
필드를 사용하여 만료를 확인할 수 있습니다. 또한 iss
필드를 사용하여 이 JWT의 원래 발행 당사자인지 확인할 수 있습니다.
서버가 토큰의 유효성에 만족하면 JWT 내부에 저장된 정보를 사용할 수 있습니다. 예를 들어, 포함된 uid
는 요청하는 사용자의 ID를 제공합니다. 이 특정 예에서는 사용자가 특정 끝점에 액세스할 수 있어야 하는지 여부를 결정할 수 있는 role
필드도 포함했습니다. (이 정보를 신뢰하는지 아니면 데이터베이스 조회를 원하는지 여부는 필요한 보안 수준에 따라 다릅니다.)
function getTodos(jwtString) { var token = JWTDecode(jwtstring); if( Date.now() < token.nbf*1000) { throw new Error('Token not yet valid'); } if( Date.now() > token.exp*1000) { throw new Error('Token has expired'); } if( token.iss != 'todoapi') { throw new Error('Token not issued here'); } var userID = token.uid; var todos = loadUserTodosFromDB(userID); return JSON.stringify(todos); }
간단한 Todo 앱을 만들어 봅시다
계속하려면 최신 버전의 Node.js(6.x 이상), npm(3.x 이상) 및 angular-cli가 설치되어 있어야 합니다. npm이 포함된 Node.js를 설치해야 하는 경우 여기의 지침을 따르세요. 이후 angular-cli
는 npm
(또는 설치한 경우 yarn
)을 사용하여 설치할 수 있습니다.
# installation using npm npm install -g @angular/cli # installation using yarn yarn global add @angular/cli
여기서 사용할 Angular 6 상용구에 대해 자세히 설명하지 않겠지만 다음 단계에서는 JWT 인증을 앱에 추가하는 단순성을 설명하기 위해 작은 할 일 애플리케이션을 보관할 Github 리포지토리를 만들었습니다. 다음을 사용하여 간단히 복제하십시오.
git clone https://github.com/sschocke/angular-jwt-todo.git cd angular-jwt-todo git checkout pre-jwt
git checkout pre-jwt
명령은 JWT가 구현되지 않은 명명된 릴리스로 전환합니다.
server
및 client
라는 두 개의 폴더가 내부에 있어야 합니다. 서버는 기본 API를 호스팅할 노드 API 서버입니다. 클라이언트는 Angular 6 앱입니다.
노드 API 서버
시작하려면 종속성을 설치하고 API 서버를 시작하십시오.
cd server # installation using npm npm install # or installation using yarn yarn node app.js
이 링크를 따라가서 데이터의 JSON 표현을 얻을 수 있어야 합니다. 지금은 인증을 받을 때까지 userID=1
에 대한 작업을 반환하도록 /todos
엔드포인트를 하드코딩했습니다.
- http://localhost:4000: 노드 서버가 실행 중인지 확인하는 테스트 페이지
- http://localhost:4000/api/users: 시스템의 사용자 목록 반환
- http://localhost:4000/api/todos:
userID=1
에 대한 작업 목록 반환
앵귤러 앱
클라이언트 앱을 시작하려면 종속 항목도 설치하고 개발 서버를 시작해야 합니다.
cd client # using npm npm install npm start # using yarn yarn yarn start
참고 : 회선 속도에 따라 모든 종속성을 다운로드하는 데 시간이 걸릴 수 있습니다.
모든 것이 잘 진행되면 http://localhost:4200으로 이동할 때 다음과 같은 내용이 표시되어야 합니다.
JWT를 통한 인증 추가
JWT 인증에 대한 지원을 추가하기 위해 사용 가능한 몇 가지 표준 라이브러리를 사용하여 더 간단하게 만들 것입니다. 물론 이러한 편리함을 포기하고 모든 것을 직접 구현할 수 있지만 여기에서 우리의 범위를 벗어납니다.
먼저 클라이언트 측에 라이브러리를 설치해 보겠습니다. 웹 사이트에 클라우드 기반 인증을 추가할 수 있는 라이브러리인 Auth0에서 개발 및 유지 관리합니다. 라이브러리 자체를 활용한다고 해서 해당 서비스를 사용할 필요는 없습니다.
cd client # installation using npm npm install @auth0/angular-jwt # installation using yarn yarn add @auth0/angular-jwt
잠시 후 코드에 도달하게 되지만 코드를 작성하는 동안 서버 측도 설정해 보겠습니다. Node가 JSON POST 본문과 JWT를 이해할 수 있도록 body-parser
, jsonwebtoken
및 express-jwt
라이브러리를 사용합니다.
cd server # installation using npm npm install body-parser jsonwebtoken express-jwt # installation using yarn yarn add body-parser jsonwebtoken express-jwt
인증을 위한 API 끝점
먼저 사용자에게 토큰을 제공하기 전에 사용자를 인증하는 방법이 필요합니다. 간단한 데모에서는 하드 코딩된 사용자 이름과 암호를 사용하여 고정 인증 끝점을 설정하기만 하면 됩니다. 이것은 애플리케이션이 요구하는 만큼 간단하거나 복잡할 수 있습니다. 중요한 것은 JWT를 다시 보내는 것입니다.
server/app.js
에서 다음과 같이 다른 require
행 아래에 항목을 추가하십시오.
const bodyParser = require('body-parser'); const jwt = require('jsonwebtoken'); const expressJwt = require('express-jwt');
뿐만 아니라 다음:
app.use(bodyParser.json()); app.post('/api/auth', function(req, res) { const body = req.body; const user = USERS.find(user => user.username == body.username); if(!user || body.password != 'todo') return res.sendStatus(401); var token = jwt.sign({userID: user.id}, 'todo-app-super-shared-secret', {expiresIn: '2h'}); res.send({token}); });
이것은 대부분 기본적인 JavaScript 코드입니다. /auth
엔드포인트에 전달된 JSON 본문을 가져오고 해당 사용자 이름과 일치하는 사용자를 찾고 사용자와 비밀번호가 일치하는지 확인하고 일치하지 않으면 401 Unauthorized
HTTP 오류를 반환합니다.
중요한 부분은 토큰 생성이며 이를 세 가지 매개변수로 분류합니다. sign
구문은 다음과 같습니다. jwt.sign(payload, secretOrPrivateKey, [options, callback])
, 여기서:
-
payload
는 토큰 내에서 인코딩하려는 키-값 쌍의 객체 리터럴입니다. 이 정보는 암호 해독 키를 가진 사람이 토큰에서 해독할 수 있습니다. 이 예에서는 인증을 위해 백엔드에서 토큰을 다시 받을 때 어떤 사용자를 처리하는지 알 수 있도록user.id
를 인코딩합니다. -
secretOrPrivateKey
는 HMAC 암호화 공유 비밀 키(단순함을 위해 앱에서 사용한 것) 또는 RSA/ECDSA 암호화 개인 키입니다. -
options
는 키-값 쌍의 형태로 인코더에 전달할 수 있는 다양한 옵션을 나타냅니다. 일반적으로 토큰이 영원히 유효하지 않고 서버가 실제로 토큰을 원래 발행했는지 확인할 수 있도록 최소한expiresIn
(exp
예약된 클레임이iss
) 및issuer
( 예약된 클레임)를 지정합니다. -
callback
은 인코딩이 완료된 후 호출하는 함수입니다. 토큰 인코딩을 비동기식으로 처리하려는 경우입니다.
( options
및 공유 비밀 키 대신 공개 키 암호화를 사용하는 방법에 대한 자세한 내용을 읽을 수도 있습니다.)
Angular 6 JWT 통합
Angular 6이 JWT와 함께 작동하도록 하는 것은 angular-jwt
를 사용하는 매우 간단합니다. client/src/app/app.modules.ts
에 다음을 추가하기만 하면 됩니다.
import { JwtModule } from '@auth0/angular-jwt'; // ... export function tokenGetter() { return localStorage.getItem('access_token'); } @NgModule({ // ... imports: [ BrowserModule, AppRoutingModule, HttpClientModule, FormsModule, // Add this import here JwtModule.forRoot({ config: { tokenGetter: tokenGetter, whitelistedDomains: ['localhost:4000'], blacklistedRoutes: ['localhost:4000/api/auth'] } }) ], // ... }
그것이 기본적으로 필요한 전부입니다. 물론 초기 인증을 수행하기 위해 추가할 코드가 더 있지만 angular-jwt
라이브러리는 모든 HTTP 요청과 함께 토큰을 보내는 것을 처리합니다.
-
tokenGetter()
함수는 말한 대로 수행하지만 구현 방법은 전적으로 사용자에게 달려 있습니다.localStorage
에 저장한 토큰을 반환하도록 선택했습니다. 물론 JSON 웹 토큰 인코딩된 문자열을 반환하는 한 원하는 다른 방법을 자유롭게 제공할 수 있습니다. -
whiteListedDomains
옵션이 존재하므로 JWT가 전송되는 도메인을 제한할 수 있으므로 공개 API도 JWT를 수신하지 않습니다. -
blackListedRoutes
옵션을 사용하면 허용된 도메인에 있는 경우에도 JWT를 수신해서는 안 되는 특정 경로를 지정할 수 있습니다. 예를 들어 인증 끝점은 아무 의미가 없기 때문에 이를 받을 필요가 없습니다. 토큰은 어쨌든 호출될 때 일반적으로 null입니다.
모든 것이 함께 작동하도록 하기
이 시점에서 API의 /auth
엔드포인트를 사용하여 주어진 사용자에 대한 JWT를 생성하는 방법이 있으며 모든 HTTP 요청과 함께 JWT를 보내기 위해 Angular에서 배관 작업을 수행했습니다. 좋습니다. 하지만 사용자에게 변경된 사항은 전혀 없다고 지적할 수 있습니다. 그리고 당신이 옳을 것입니다. 우리는 여전히 앱의 모든 페이지를 탐색할 수 있으며 JWT를 보내지 않고도 모든 API 엔드포인트를 호출할 수 있습니다. 안좋다!

누가 로그인했는지 확인하려면 클라이언트 앱을 업데이트해야 하고 JWT가 필요하도록 API도 업데이트해야 합니다. 시작하자.
로그인을 위해 새로운 Angular 구성 요소가 필요합니다. 간결함을 위해 가능한 한 간단하게 유지하겠습니다. 또한 모든 인증 요구 사항을 처리하는 서비스와 로그인하기 전에 액세스할 수 없는 경로를 보호하는 Angular Guard가 필요합니다. 클라이언트 애플리케이션 컨텍스트에서 다음을 수행합니다.
cd client ng g component login --spec=false --inline-style ng g service auth --flat --spec=false ng g guard auth --flat --spec=false
이렇게 하면 client
폴더에 4개의 새 파일이 생성되어야 합니다.
src/app/login/login.component.html src/app/login/login.component.ts src/app/auth.service.ts src/app/auth.guard.ts
다음으로 앱에 대한 인증 서비스와 가드를 제공해야 합니다. client/src/app/app.modules.ts
업데이트:
import { AuthService } from './auth.service'; import { AuthGuard } from './auth.guard'; // ... providers: [ TodoService, UserService, AuthService, AuthGuard ],
그런 다음 client/src/app/app-routing.modules.ts
에서 라우팅을 업데이트하여 인증 가드를 사용하고 로그인 구성 요소에 대한 경로를 제공합니다.
// ... import { LoginComponent } from './login/login.component'; import { AuthGuard } from './auth.guard'; const routes: Routes = [ { path: 'todos', component: TodoListComponent, canActivate: [AuthGuard] }, { path: 'users', component: UserListComponent, canActivate: [AuthGuard] }, { path: 'login', component: LoginComponent}, // ...
마지막으로 client/src/app/auth.guard.ts
를 다음 내용으로 업데이트합니다.
import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; @Injectable() export class AuthGuard implements CanActivate { constructor(private router: Router) { } canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) { if (localStorage.getItem('access_token')) { return true; } this.router.navigate(['login']); return false; } }
데모 애플리케이션의 경우 로컬 스토리지에 JWT가 있는지 확인하기만 하면 됩니다. 실제 응용 프로그램에서는 토큰을 디코딩하고 유효성, 만료 등을 확인합니다. 예를 들어 이를 위해 JwtHelperService를 사용할 수 있습니다.
이 시점에서 Angular 앱은 로그인할 방법이 없기 때문에 항상 로그인 페이지로 리디렉션합니다. client/src/app/auth.service.ts
의 인증 서비스부터 시작하여 이를 수정하겠습니다.
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable() export class AuthService { constructor(private http: HttpClient) { } login(username: string, password: string): Observable<boolean> { return this.http.post<{token: string}>('/api/auth', {username: username, password: password}) .pipe( map(result => { localStorage.setItem('access_token', result.token); return true; }) ); } logout() { localStorage.removeItem('access_token'); } public get loggedIn(): boolean { return (localStorage.getItem('access_token') !== null); } }
우리의 인증 서비스에는 login
과 logout
의 두 가지 기능만 있습니다.
-
login
POST
는 제공된username
과password
를 백엔드에 제공하고 다시 수신하면localStorage
에access_token
을 설정합니다. 단순함을 위해 여기에는 오류 처리가 없습니다. -
logout
은 단순히localStorage
에서access_token
을 지우고 추가로 액세스하려면 먼저 새 토큰을 획득해야 합니다. -
loggedIn
은 사용자가 로그인했는지 여부를 확인하는 데 빠르게 사용할 수 있는 부울 속성입니다.
마지막으로 로그인 구성 요소입니다. 이것들은 실제로 JWT로 작업하는 것과 관련이 없으므로 자유롭게 복사하여 client/src/app/login/login.components.html
에 붙여넣으세요.
<h4 *ngIf="error">{{error}}</h4> <form (ngSubmit)="submit()"> <div class="form-group col-3"> <label for="username">Username</label> <input type="text" name="username" class="form-control" [(ngModel)]="username" /> </div> <div class="form-group col-3"> <label for="password">Password</label> <input type="password" name="password" class="form-control" [(ngModel)]="password" /> </div> <div class="form-group col-3"> <button class="btn btn-primary" type="submit">Login</button> </div> </form>
그리고 client/src/app/login/login.components.ts
는 다음이 필요합니다:
import { Component, OnInit } from '@angular/core'; import { AuthService } from '../auth.service'; import { Router } from '@angular/router'; import { first } from 'rxjs/operators'; @Component({ selector: 'app-login', templateUrl: './login.component.html' }) export class LoginComponent { public username: string; public password: string; public error: string; constructor(private auth: AuthService, private router: Router) { } public submit() { this.auth.login(this.username, this.password) .pipe(first()) .subscribe( result => this.router.navigate(['todos']), err => this.error = 'Could not authenticate' ); } }
Voila, Angular 6 로그인 예:
이 단계에서 우리는 ( jemma
, paul
또는 sebastian
을 사용하여 비밀번호 todo
를 사용하여) 로그인하고 모든 화면을 다시 볼 수 있어야 합니다. 그러나 우리 애플리케이션은 동일한 탐색 헤더를 표시하며 현재 상태에 관계없이 로그아웃할 방법이 없습니다. API 수정으로 넘어가기 전에 수정하겠습니다.
client/src/app/app.component.ts
에서 전체 파일을 다음으로 바꿉니다.
import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { AuthService } from './auth.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(private auth: AuthService, private router: Router) { } logout() { this.auth.logout(); this.router.navigate(['login']); } }
그리고 client/src/app/app.component.html
의 경우 <nav>
섹션을 다음으로 바꿉니다.
<nav class="nav nav-pills"> <a class="nav-link" routerLink="todos" routerLinkActive="active" *ngIf="auth.loggedIn">Todo List</a> <a class="nav-link" routerLink="users" routerLinkActive="active" *ngIf="auth.loggedIn">Users</a> <a class="nav-link" routerLink="login" routerLinkActive="active" *ngIf="!auth.loggedIn">Login</a> <a class="nav-link" (click)="logout()" href="#" *ngIf="auth.loggedIn">Logout</a> </nav>
사용자가 로그인했는지 여부에 따라 특정 항목만 표시해야 한다는 컨텍스트 인식 탐색을 만들었습니다. auth.loggedIn
은 물론 인증 서비스를 가져올 수 있는 모든 곳에서 사용할 수 있습니다.
API 보안
당신은 이것이 훌륭하다고 생각할 수도 있습니다. 모든 것이 훌륭하게 작동하는 것 같습니다 . 그러나 세 가지 다른 사용자 이름으로 로그인을 시도하면 다음과 같은 사실을 알 수 있습니다. 모두 동일한 할 일 목록을 반환합니다. API 서버를 살펴보면 실제로 각 사용자가 고유한 항목 목록을 가지고 있음을 알 수 있습니다.
글쎄, 우리가 시작할 때 /todos
API 끝점을 코딩하여 항상 userID=1
에 대한 할 일 목록을 반환했음을 기억하십시오. 현재 로그인한 사용자가 누구인지 알 수 있는 방법이 없었기 때문입니다.
이제 끝점을 보호하고 JWT에 인코딩된 정보를 사용하여 필요한 사용자 ID를 제공하는 것이 얼마나 쉬운지 살펴보겠습니다. 처음에 마지막 app.use()
호출 바로 아래에 있는 server/app.js
파일에 다음 한 줄을 추가합니다.
app.use(expressJwt({secret: 'todo-app-super-shared-secret'}).unless({path: ['/api/auth']}));
우리는 express-jwt
미들웨어를 사용하고 공유 비밀이 무엇인지 알려주고 JWT가 필요하지 않은 경로 배열을 지정합니다. 그리고 그게 다야. 모든 끝점을 건드릴 필요가 없고, if
문을 전체적으로 만들거나, 무엇이든 할 필요가 없습니다.
내부적으로 미들웨어는 몇 가지 가정을 하고 있습니다. 예를 들어 Authorization
HTTP 헤더가 Bearer {token}
의 공통 JWT 패턴을 따른다고 가정합니다. (라이브러리에는 그렇지 않은 경우 작동 방식을 사용자 정의할 수 있는 많은 옵션이 있습니다. 자세한 내용은 express-jwt 사용법을 참조하십시오.)
두 번째 목표는 JWT로 인코딩된 정보를 사용하여 누가 전화를 걸고 있는지 알아내는 것입니다. 다시 한번 express-jwt
가 구출됩니다. 토큰을 읽고 확인하는 과정에서 서명 프로세스에서 보낸 인코딩된 페이로드를 Express의 req.user
변수로 설정합니다. 그런 다음 이를 사용하여 저장한 모든 변수에 즉시 액세스할 수 있습니다. 우리의 경우 userID
를 인증된 사용자의 ID와 동일하게 설정하므로 req.user.userID
로 직접 사용할 수 있습니다.
server/app.js
를 다시 업데이트하고 /todos
엔드포인트를 다음과 같이 변경합니다.
res.send(getTodos(req.user.userID));
그리고 그게 다야. 이제 API가 무단 액세스로부터 보호되며 모든 엔드포인트에서 인증된 사용자가 누구인지 안전하게 확인할 수 있습니다. 또한 클라이언트 애플리케이션에는 간단한 인증 프로세스가 있으며 API 엔드포인트를 호출하는 작성하는 모든 HTTP 서비스에는 자동으로 인증 토큰이 첨부됩니다.
Github 리포지토리를 복제하고 최종 결과를 실제로 보고 싶다면 다음을 사용하여 최종 형식의 코드를 확인할 수 있습니다.
git checkout with-jwt
이 연습이 자신의 Angular 앱에 JWT 인증을 추가하는 데 유용하다는 것을 알게 되었기를 바랍니다. 읽어 주셔서 감사합니다!