Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Nest.js login
- gcp ssh vm
- jwt장점
- ssh 연결 방법
- vm ssh 포트 변경
- docker mysql설치하기
- ssh 포트 변경
- Nest.js
- How to Join Tables Without Relations in TypeORM
- ssh연결
- ssh vm연결
- 맥 포트확인
- vm ssh port
- local database
- macOS ssh
- InnerJoinMapOne
- port 22: Operation timed out
- nest login
- 맥 포트닫기
- JWT
- gcp ssh 포트 변경
- JWT쓰는이유
- vm ssh 포트
- vm ssh
- gcp ssh
- 맥 사용하는 포트 확인
- nest authentication
- Nest.js 로그인
- nest passport
- nest jwt
Archives
- Today
- Total
Seize the day
[Nest.js] Login Authentication 구현 ( passport + jwt + local strategy ) 본문
개발/Node.js
[Nest.js] Login Authentication 구현 ( passport + jwt + local strategy )
nofunfromdev 2022. 4. 4. 00:37사용자인증은 대부분의 애플리케이션에서 필수적인 부분이다. 인증을 처리하는 방법은 다양하지만 Nest.js 공식홈페이지에서 passport를 안내하고 있어 필자는 passport와 jwt를 선택했다. jwt 전략을 사용 하기 전 passport-local을 먼저 구현하였다.
Nest.js로 Login 구현하기 (1)
패키지 설치 및 모듈 생성
$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
패키지를 설치 후 모듈과 서비스를 생성한다.
$ nest g module auth
$ nest g service auth --no-spec
$ nest g module user
$ nest g service user --no-spec
passport local Strategy
// user/user.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from 'src/entity/user.entity';
import { Repository } from 'typeorm';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}
async findOne(id: string): Promise<User | undefined> {
return this.userRepository.findOne({
where: {
id: id,
}
});
}
}
// auth/auth.service.ts
import { Injectable } from '@nestjs/common';
import { UserService } from '../user/user.service';
import * as bcrypt from 'bcrypt';
@Injectable()
export class AuthService {
constructor(private userService: UserService) {}
async validateUser(id: string, password: string): Promise<any> {
const user = await this.userService.findOne(id);
if (!(await bcrypt.compare(password, user?.password ?? ''))) {
return null;
}
return user;
}
}
나는 typeorm
을 사용하여 데이터베이스에서 사용자 검색을 하였다. 데이터베이스에는 해시된 암호만 저장한 후 데이터를 비교하였다. bcrypt 라이브러리로 단방향해시 알고리즘을 사용하였다.
// auth/local.strategy.ts
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({ usernameField: 'id' });
}
async validate(id: string, password: string): Promise<any> {
const user = await this.authService.validateUser(id, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
super()
을 호출하면서 옵션을 전달 할 수 있는데, default로 request는 username
과 password
속성이 필요하다. 다른 속성이름으로 지정하려면 super({usernameField: 'id'}
라고 옵션을 설정하면 된다.
// auth/guard/local-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
// app.controller.ts
import { Controller, Get, Post, UseGuards, Request } from '@nestjs/common';
import { AppService } from './app.service';
import { LocalAuthGuard } from './auth/guard/local-auth.guard';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
return req.user;
}
}
$ curl -X POST http://localhost:3000/auth/login -d '{"id": "nofunfromdev", "password": "test"}' -H "Content-Type: application/json"
validate()에서 반환되는 값은 자동으로 사용자 개체를 생성하여 req.user로 Request에 할당된다.
터미널에서 실행하면 정상적으로 사용자 값이 return 된다.
참고사이트
- https://docs.nestjs.com/security/authentication
반응형
'개발 > Node.js' 카테고리의 다른 글
Comments