Programming/JavaScript & TypeScript

[Node Express - Angular5] JWT 기반 사용자 인증 개발 - Angular 편

Bonita SY 2019. 5. 3. 17:13
728x90
반응형

[ Angular Version 정보 ]

Angular CLI: 1.7.4
OS: linux x64
Angular: 5.2.11
@angular/cdk: 6.4.7
@angular/cli: 1.7.4
@angular/material: 6.4.7
@angular-devkit/build-optimizer: 0.11.4
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.40
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.10.2
@schematics/angular: 0.3.2
@schematics/package-update: 0.3.2
@schematics/schematics: 0.0.10
typescript: 2.4.2
webpack-cli: 3.2.1
webpack-dev-server: 2.9.7
webpack: 3.10.0

 

[ 사용한 Angular JWT NPM 정보 ]

"@auth0/angular-jwt": "^2.1.0"


① npm 설치

npm install @auth0/angular-jwt --save

 

②  app.module.ts 내 해당 모듈 import

import { JwtModule } from '@auth0/angular-jwt';



export function tokenGetter() { 
  return localStorage.getItem('jwt_token'); 
}



@NgModule({

  imports: [

    JwtModule.forRoot({ 
        config: { 
            tokenGetter: tokenGetter 
        } 
    })

...

 

③ auth.service.ts 파일 생성 및 구현

⑴ 파일 생성

ng g s auth --module=app.module.ts

--module 옵션을 줘야 module파일에 직접 서비스 등록안해도 되고, 좋음

 

⑵ 소스 구현

생성된 auth.service.ts 파일열면 자동으로 있는거 건들지 않고, 추가함

import { HttpClient } from '@angular/common/http'; 
import { Observable } from 'rxjs/Observable'; 
import { JwtHelperService } from '@auth0/angular-jwt';

import 'rxjs/add/observable/of';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/shareReplay';

const helper = new JwtHelperService();

우선 나는 server랑 통신해야하니까 HttpClient 넣고, 동기적으로 처리해야하니까 Observable 모듈 넣음

 

그리고 아까 설치한 모듈 사용하기 위한 서비스 모듈 JwtHelperService import 하고, 해당 서비스 모듈을  const 변수에 담음 ㅎ

 

이제 class 안에다가 주요 함수 구현!!!!!!

@Injectable() 
export class AuthService { 
  constructor(private http: HttpClient) { }



  signIn(user_info: any): Observable { 
    return this.http.post('/login', user_info) 
                    .do(res => { 
                        this.setToken(res.token); 
                    }) 
                    .shareReplay(); 
  } 

  signOut(): void { 
    this.removeToken(); 
  } 

  isAuthenticated(): boolean { 
    let token = this.getToken(); 
    return token? !this.isTokenExpired(token) : false; 
  } 

  getToken(): string { 
    return localStorage.getItem('jwt_token'); 
  } 

  setToken(token: string): void { 
    localStorage.setItem('jwt_token', token); 
  } 

  removeToken(): void { 
    localStorage.removeItem('jwt_token'); 
  } 

  isTokenExpired(token: string) { 
    return helper.isTokenExpired(token); 
  } 

  getUserid(): string { 
    return helper.decodeToken(this.getToken()).id; 
  }

...

- signIn() : WEB server에 login 요청하고, server가 만들어준 jwt를 localStorage에 저장

- signOut() : localStorage에 있는 jwt 삭제

- isAuthenticated() : localStorage에 있는 jwt를 가져와서, 그 토큰이 유효한지 체크

- getToken() : localStorage에서 jwt를 실질적으로 조회

- setToken() : localStorage에 jwt를 실직적으로 셋팅

- removeToken() : localStorage에 jwt를 실질적으로 제거

- isTokenExpired() : jwt 서비스 모듈을 이용해서 jwt 유효 여부를 return

- getUserid() : jwt가 갖고 있는 사용자 정보를 decode하여 return

 

④ *.component.ts 파일에서 auth.service.ts 사용

import { AuthService } from '../auth.service';

constructor(..., private auth: AuthService) { }

사용을 위해 service 파일을 import 하고, constructor에 등록

  getJwt(pwd) { 
    if(pwd) { 
        let regExp:RegExp = /[\{\}\[\]\/?,;:|\)*~`!^\-_+<>\#$%&\\\=\(\'\"]/gi; 
        if ((regExp.test(pwd)) || (pwd.length >= 50)) { 
            alert('사용자 정보가 없습니다.'); 
        } else { 
            let infor = { 
                id: this.id, 
                pwd: pwd 
            }; 

            this.auth.signIn(infor).subscribe( 
                data => { 
                    if(data.status === True) {
                        this.router.navigateByUrl('/'); 
                    } else { 
                        alert("사용자 정보가 없습니다."); 
                    } 
                }, 
                ({error}) => { 
                    alert("사용자 정보가 없습니다."); 
                } 
            ); 
        } 
    } 
  }

이런 식으로 함수 선언해서, 사용하면 됨~

 

* server는 다음 포스트에..

 

 

 

※ 출처 (JWT 구현하느라고 고생을 너무 많이한 흔적,, 한번이라도 참고해본 것들은 그냥 다 넣음,,)

https://velopert.com/2448

- https://www.npmjs.com/package/express-jwt

https://stackblitz.com/angular/aedmpnmngnn

https://angular.io/guide/dependency-injection-in-action

http://expressjs.com/ko/api.html

https://poiemaweb.com/angular-jwt-authentication

https://www.a-mean-blog.com/ko/blog/Angular-2/%EA%B8%B0%EB%B3%B8%EC%82%AC%EC%9D%B4%ED%8A%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0/Reactive-Forms-Module-%EB%A1%9C-Login-Form-%EB%A7%8C%EB%93%A4%EA%B8%B0

https://www.npmjs.com/package/jsonwebtoken

https://www.npmjs.com/package/auth0-js

https://auth0.com/blog/angular-2-authentication/

https://github.com/auth0/angular2-jwt/issues/537

https://gist.github.com/thebigredgeek/230368bd92aa19e3f6638b659edf5cef

https://github.com/auth0/angular2-jwt/issues/435

https://github.com/auth0/angular2-jwt/issues/493

https://github.com/auth0/angular2-jwt

https://github.com/auth0/angular2-jwt/issues/539

https://github.com/auth0/angular2-jwt/issues/476

https://www.npmjs.com/package/@auth0/angular-jwt

https://blog.angular-university.io/angular-jwt-authentication/

https://www.npmjs.com/package/jsonwebtoken

https://stackoverflow.com/questions/47753743/cannot-set-headers-after-they-are-sent-to-the-client

https://github.com/mozilla/nunjucks/issues/652

728x90
반응형