nestjs_auth...

This commit is contained in:
최준흠 2022-09-14 17:53:11 +09:00
parent d5e6e88461
commit 32ffb17486
10 changed files with 105 additions and 23 deletions

3
.env
View File

@ -18,8 +18,7 @@ JWT_CONSTANTS_ACCESS_SECRET = "access_key"
JWT_CONSTANTS_ACCESS_EXPIRESIN ="60s" JWT_CONSTANTS_ACCESS_EXPIRESIN ="60s"
JWT_CONSTANTS_REFRESH_SECRET = "refresh_key" JWT_CONSTANTS_REFRESH_SECRET = "refresh_key"
JWT_CONSTANTS_REPRESH_EXPIRESIN ="1d" JWT_CONSTANTS_REFRESH_EXPIRESIN ="1d"
JWT_CONSTANTS_REPRESH_SALTORROUNDS=10
DEFAULT_TABLE_PERPAGE = 10 DEFAULT_TABLE_PERPAGE = 10
DEFAULT_TABLE_PAGE = 1 DEFAULT_TABLE_PAGE = 1

View File

@ -2,7 +2,8 @@
import { Body, Controller, Get, Post, UseGuards, Request } from '@nestjs/common' import { Body, Controller, Get, Post, UseGuards, Request } from '@nestjs/common'
import { UserDTO } from 'src/user/dtos/user.dto' import { UserDTO } from 'src/user/dtos/user.dto'
import { AuthService } from './auth.service' import { AuthService } from './auth.service'
import { JwtAuthGuard } from './guards/jwt.auth.guard' import { JwtAccessTokenGuard } from './guards/jwt.accesstoken.guard'
import { JwtRefreshTokenGuard } from './guards/jwt.refreshtoken.guard'
import { LocalAuthGuard } from './guards/local.auth.guard' import { LocalAuthGuard } from './guards/local.auth.guard'
@Controller('auth') @Controller('auth')
@ -17,12 +18,19 @@ export class AuthController {
} }
//jwt.strategy의 validate에서 true인경우 넘어옴 //jwt.strategy의 validate에서 true인경우 넘어옴
@UseGuards(JwtAuthGuard) @UseGuards(JwtAccessTokenGuard)
@Get('profile') @Get('profile')
async getProfile(@Request() req) { async profile(@Request() req) {
return req.user return req.user
} }
//jwt.strategy의 validate에서 true인경우 넘어옴
@UseGuards(JwtRefreshTokenGuard)
@Get('reload')
async reload(@Request() req) {
return await this.authService.reload(req.user)
}
//사용자 등록 //사용자 등록
@Post('register') @Post('register')
async add(@Body() data: UserDTO) { async add(@Body() data: UserDTO) {

View File

@ -8,7 +8,8 @@ import { AuthService } from './auth.service'
import { JwtModule } from '@nestjs/jwt' import { JwtModule } from '@nestjs/jwt'
import { AuthController } from './auth.controller' import { AuthController } from './auth.controller'
import { LocalStrategy } from './guards/local.strategy' import { LocalStrategy } from './guards/local.strategy'
import { JwtAuthStrategy } from './guards/jwt.auth.stragy' import { JwtAccessTokenStrategy } from './guards/jwt.accesstoken.stragy'
import { JwtRefreshTokenStrategy } from './guards/jwt.refreshtoken.stragy'
import { UsersModule } from '../user/user.module' import { UsersModule } from '../user/user.module'
import { jwtConstants } from './guards/jwt.constants' import { jwtConstants } from './guards/jwt.constants'
@ -22,7 +23,12 @@ import { jwtConstants } from './guards/jwt.constants'
}) })
], ],
controllers: [AuthController], controllers: [AuthController],
providers: [AuthService, LocalStrategy, JwtAuthStrategy], providers: [
AuthService,
LocalStrategy,
JwtAccessTokenStrategy,
JwtRefreshTokenStrategy
],
exports: [AuthService] exports: [AuthService]
}) })
export class AuthModule {} export class AuthModule {}

View File

@ -39,7 +39,7 @@ export class AuthService {
} }
async register(data: UserDTO): Promise<any> { async register(data: UserDTO): Promise<any> {
data.refresh_token = await this.getRefreshToken() data.refresh_token = await this.getRefreshToken(data)
data.password = await this.getEcryptedPassword(data.password) data.password = await this.getEcryptedPassword(data.password)
return await this.login(await this.userService.add(data)) return await this.login(await this.userService.add(data))
} }
@ -78,9 +78,12 @@ export class AuthService {
expiresIn: jwtConstants.access_expiresIn expiresIn: jwtConstants.access_expiresIn
} }
} }
async getRefreshToken(): Promise<any> { async getRefreshToken(data: UserDTO): Promise<any> {
const token = await this.jwtService.sign( const token = await this.jwtService.sign(
{}, {
email: data.email,
name: data.name
},
{ {
secret: jwtConstants.access_secret, secret: jwtConstants.access_secret,
expiresIn: jwtConstants.refresh_expiresIn expiresIn: jwtConstants.refresh_expiresIn
@ -94,7 +97,7 @@ export class AuthService {
async getTokens(data: UserDTO): Promise<any> { async getTokens(data: UserDTO): Promise<any> {
return { return {
access_token: await this.getAccessToken(data), access_token: await this.getAccessToken(data),
refresh_token: await this.getRefreshToken() refresh_token: await this.getRefreshToken(data)
} }
} }
} }

View File

@ -7,7 +7,7 @@ import { AuthGuard } from '@nestjs/passport'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
@Injectable() @Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') { export class JwtAccessTokenGuard extends AuthGuard('accesstoken') {
canActivate( canActivate(
context: ExecutionContext context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> { ): boolean | Promise<boolean> | Observable<boolean> {

View File

@ -4,13 +4,16 @@ import { Injectable, UnauthorizedException } from '@nestjs/common'
import { jwtConstants } from './jwt.constants' import { jwtConstants } from './jwt.constants'
import { AuthService } from '../auth.service' import { AuthService } from '../auth.service'
type jwtPayloadType = { type jwtPayloadAccessToken = {
email: string email: string
name: string name: string
} }
@Injectable() @Injectable()
export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') { export class JwtAccessTokenStrategy extends PassportStrategy(
Strategy,
'accesstoken'
) {
constructor(private authService: AuthService) { constructor(private authService: AuthService) {
super({ super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
@ -20,7 +23,7 @@ export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') {
} }
//AccessToken 인증 //AccessToken 인증
async validate(payload: jwtPayloadType) { async validate(payload: jwtPayloadAccessToken) {
try { try {
return await this.authService.validateUser({ return await this.authService.validateUser({
email: payload.email, email: payload.email,

View File

@ -1,7 +1,7 @@
export const jwtConstants = { export const jwtConstants = {
access_secret: process.env.JWT_CONSTANTS_ACCESS_SECRET, access_secret: process.env.JWT_CONSTANTS_ACCESS_SECRET,
access_expiresIn: process.env.JWT_CONSTANTS_ACCESS_EXPIRESIN, access_expiresIn: process.env.JWT_CONSTANTS_ACCESS_EXPIRESIN,
refresh_secret: process.env.JWT_CONSTANTS_REPRESH_SECRET, refresh_secret: process.env.JWT_CONSTANTS_REFRESH_SECRET,
refresh_expiresIn: process.env.JWT_CONSTANTS_REPRESH_EXPIRESIN, refresh_expiresIn: process.env.JWT_CONSTANTS_REFRESH_EXPIRESIN,
password_saltorRounds: process.env.AUTH_PASSWORD_SALTORROUNDS password_saltorRounds: process.env.AUTH_PASSWORD_SALTORROUNDS
} }

View File

@ -0,0 +1,27 @@
import {
ExecutionContext,
Injectable,
UnauthorizedException
} from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'
import { Observable } from 'rxjs'
@Injectable()
export class JwtRefreshTokenGuard extends AuthGuard('refreshtoken') {
canActivate(
context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> {
// Add your custom authentication logic here
// for example, call super.logIn(request) to establish a session.
return super.canActivate(context)
}
handleRequest(err, user, info) {
// You can throw an exception based on either "info" or "err" arguments
if (err || !user) {
throw err || new UnauthorizedException()
}
console.log('JwtRefreshTokenGuard.handleRequest().info =>' + info)
return user
}
}

View File

@ -0,0 +1,36 @@
import { ExtractJwt, Strategy } from 'passport-jwt'
import { PassportStrategy } from '@nestjs/passport'
import { Injectable, UnauthorizedException } from '@nestjs/common'
import { jwtConstants } from './jwt.constants'
import { AuthService } from '../auth.service'
type jwtPayloadRefreshToken = {
email: string
name: string
}
@Injectable()
export class JwtRefreshTokenStrategy extends PassportStrategy(
Strategy,
'refreshtoken'
) {
constructor(private authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: jwtConstants.refresh_secret
})
}
//AccessToken 인증
async validate(payload: jwtPayloadRefreshToken) {
try {
return await this.authService.validateUser({
email: payload.email,
name: payload.name
})
} catch (e) {
throw new UnauthorizedException(e)
}
}
}

View File

@ -14,7 +14,7 @@ import { User } from '@prisma/client'
import { UserDTO } from './dtos/user.dto' import { UserDTO } from './dtos/user.dto'
import { UserService } from './user.service' import { UserService } from './user.service'
import { Roles } from '../auth/decorators/roles.decorator' import { Roles } from '../auth/decorators/roles.decorator'
import { JwtAuthGuard } from '../auth/guards/jwt.auth.guard' import { JwtAccessTokenGuard } from '../auth/guards/jwt.accesstoken.guard'
import { RolesGuard } from '../auth/guards/roles.guard' import { RolesGuard } from '../auth/guards/roles.guard'
import { ROLE } from '@prisma/client' import { ROLE } from '@prisma/client'
@ -23,7 +23,7 @@ export class UserController {
constructor(private readonly userService: UserService) {} constructor(private readonly userService: UserService) {}
@Roles(ROLE.ADMIN) @Roles(ROLE.ADMIN)
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAccessTokenGuard, RolesGuard)
@Get() @Get()
async fetchAll(@Query() query) { async fetchAll(@Query() query) {
console.log(query) console.log(query)
@ -130,21 +130,21 @@ export class UserController {
} }
@Roles(ROLE.ADMIN) @Roles(ROLE.ADMIN)
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAccessTokenGuard, RolesGuard)
@Get(':id') @Get(':id')
async fetchOne(@Param('id') id: string) { async fetchOne(@Param('id') id: string) {
return await this.userService.fetchOne({ id: Number(id) }) return await this.userService.fetchOne({ id: Number(id) })
} }
@Roles(ROLE.ADMIN) @Roles(ROLE.ADMIN)
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAccessTokenGuard, RolesGuard)
@Post('add') @Post('add')
async add(@Body() data: UserDTO) { async add(@Body() data: UserDTO) {
return await this.userService.add(data) return await this.userService.add(data)
} }
@Roles(ROLE.ADMIN) @Roles(ROLE.ADMIN)
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAccessTokenGuard, RolesGuard)
@Put(':id') @Put(':id')
async update(@Param('id') id: string, @Body() data: UserDTO) { async update(@Param('id') id: string, @Body() data: UserDTO) {
data.updatedAt = new Date() data.updatedAt = new Date()
@ -155,7 +155,7 @@ export class UserController {
} }
@Roles(ROLE.ADMIN) @Roles(ROLE.ADMIN)
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAccessTokenGuard, RolesGuard)
@Delete(':id') @Delete(':id')
async delete(@Param('id') id: string): Promise<User | undefined> { async delete(@Param('id') id: string): Promise<User | undefined> {
return await this.userService.remove({ id: Number(id) }) return await this.userService.remove({ id: Number(id) })