nestjs_auth...

This commit is contained in:
최준흠 2022-09-10 18:48:13 +09:00
parent a73e85cf45
commit 35a4c76477
11 changed files with 36 additions and 64 deletions

8
.env
View File

@ -10,13 +10,11 @@ CORS_ALLOW_METHOD = "GET,PUT,POST,DELETE,PATCH,OPTIONS"
AUTH_USERNAME_FIELD="email" AUTH_USERNAME_FIELD="email"
JWT_REFRESH_TOKEN_SECRET = "security_key" JWT_CONSTANTS_SECRET = "security_key"
JWT_REFRESH_TOKEN_EXPIREIN = "14d" JWT_CONSTANTS_EXPIRESIN ="60s"
JWT_REFRESH_TOKEN_ISSUER = "idcjp"
JWT_ACCESS_TOKEN_SECRET = "security_key" JWT_REFRESH_TOKEN_EXPIREIN = "14d"
JWT_ACCESS_TOKEN_EXPIREIN = "60s" JWT_ACCESS_TOKEN_EXPIREIN = "60s"
JWT_ACCESS_TOKEN_ISSUER = "idcjp"
DEFAULT_TABLE_PERPAGE = 10 DEFAULT_TABLE_PERPAGE = 10
DEFAULT_TABLE_PAGE = 1 DEFAULT_TABLE_PAGE = 1

View File

@ -18,16 +18,17 @@ import { LocalAuthGuard } from './guards/local.auth.guard'
export class AuthController { export class AuthController {
constructor(private authService: AuthService) {} constructor(private authService: AuthService) {}
//Login용
@UseGuards(LocalAuthGuard) @UseGuards(LocalAuthGuard)
//local.strategy의 validate에서 Login처리후 넘어옴
//결과오류시 NotFoundError: No User found라고 console log에 출력됨
@Post('login') @Post('login')
login(@Param('email') email: string, @Param('password') password: string) { async login(@Request() req) {
//console.log(req) return this.authService.getTokens(req.user)
return this.authService.login(email, password)
} }
//Profile 여부 확인용 //Profile 여부 확인용
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
//jwt.strategy의 validate에서 token확인후 넘어옴
@Get('profile') @Get('profile')
getProfile(@Request() req) { getProfile(@Request() req) {
//console.log(req) //console.log(req)

View File

@ -6,7 +6,7 @@ import { Module } from '@nestjs/common'
import { PassportModule } from '@nestjs/passport' import { PassportModule } from '@nestjs/passport'
import { AuthService } from './auth.service' import { AuthService } from './auth.service'
import { JwtModule } from '@nestjs/jwt' import { JwtModule } from '@nestjs/jwt'
import { jwtAcceesTokenOptions } from './guards/jwt.constants' import { jwtConstants } from './guards/jwt.constants'
import { AuthController } from './auth.controller' import { AuthController } from './auth.controller'
import { LocalStrategy } from './guards/local.strategy' import { LocalStrategy } from './guards/local.strategy'
import { JwtStrategy } from './guards/jwt.strategy' import { JwtStrategy } from './guards/jwt.strategy'
@ -17,8 +17,8 @@ import { UsersModule } from '../user/user.module'
UsersModule, UsersModule,
PassportModule, PassportModule,
JwtModule.register({ JwtModule.register({
secret: jwtAcceesTokenOptions.secret, secret: jwtConstants.secret,
signOptions: { expiresIn: jwtAcceesTokenOptions.expiresIn } signOptions: { expiresIn: jwtConstants.expiresIn }
}) })
], ],
controllers: [AuthController], controllers: [AuthController],

View File

@ -4,11 +4,6 @@ import { JwtService } from '@nestjs/jwt'
import { User } from '@prisma/client' import { User } from '@prisma/client'
import { UserDTO } from 'src/user/dtos/user.dto' import { UserDTO } from 'src/user/dtos/user.dto'
import { UserService } from '../user/user.service' import { UserService } from '../user/user.service'
import {
jwtAcceesTokenOptions,
jwtRefreshTokenTypes
} from './guards/jwt.constants'
@Injectable() @Injectable()
export class AuthService { export class AuthService {
constructor( constructor(
@ -22,8 +17,6 @@ export class AuthService {
if (user && user.password === password) { if (user && user.password === password) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { password, ...result } = user const { password, ...result } = user
// result는 password 를 제외한 user의 모든 정보를 포함한다.
//console.log(result)
return result return result
} }
return null return null
@ -36,27 +29,14 @@ export class AuthService {
name: user.name name: user.name
} }
const refresh_token_payload = {} const refresh_token_payload = {}
// console.log(payload)
return { return {
tokens: { tokens: {
access_token: this.jwtService.sign( access_token: this.jwtService.sign(access_token_payload),
access_token_payload, refresh_token: this.jwtService.sign(refresh_token_payload)
jwtAcceesTokenOptions
),
refresh_token: this.jwtService.sign(
refresh_token_payload,
jwtRefreshTokenTypes
)
} }
} }
} }
async login(email: string, password: string): Promise<any | null> {
const user = await this.validateUser(email, password)
if (!user) return null
return await this.getTokens(user)
}
async register(data: UserDTO): Promise<any | null> { async register(data: UserDTO): Promise<any | null> {
const user = await this.userService.add(data) const user = await this.userService.add(data)
if (!user) return null if (!user) return null

View File

@ -13,7 +13,6 @@ export class JwtAuthGuard extends AuthGuard('jwt') {
): boolean | Promise<boolean> | Observable<boolean> { ): boolean | Promise<boolean> | Observable<boolean> {
// Add your custom authentication logic here // Add your custom authentication logic here
// for example, call super.logIn(request) to establish a session. // for example, call super.logIn(request) to establish a session.
console.log(context)
return super.canActivate(context) return super.canActivate(context)
} }
@ -22,7 +21,7 @@ export class JwtAuthGuard extends AuthGuard('jwt') {
if (err || !user) { if (err || !user) {
throw err || new UnauthorizedException() throw err || new UnauthorizedException()
} }
console.log(info) console.log('JwtAuthGuard.handleRequest().info =>' + info)
return user return user
} }
} }

View File

@ -1,11 +1,4 @@
export const jwtAcceesTokenOptions = { export const jwtConstants = {
secret: process.env.JWT_ACCESS_TOKEN_SECRET, secret: process.env.JWT_CONSTANTS_SECRET,
expiresIn: process.env.JWT_ACCESS_TOKEN_EXPIREIN, expiresIn: process.env.JWT_CONSTANTS_EXPIRESIN
issuer: process.env.JWT_ACCESS_TOKEN_ISSUER
}
export const jwtRefreshTokenTypes = {
secret: process.env.JWT_REFRESH_TOKEN_SECRET,
expiresIn: process.env.JWT_REFRESH_TOKEN_EXPIREIN,
issuer: process.env.JWT_REFRESH_TOKEN_ISSUER
} }

View File

@ -1,7 +1,6 @@
import { ExtractJwt, Strategy } from 'passport-jwt' import { ExtractJwt, Strategy } from 'passport-jwt'
import { PassportStrategy } from '@nestjs/passport' import { PassportStrategy } from '@nestjs/passport'
import { Injectable } from '@nestjs/common' import { Injectable } from '@nestjs/common'
import { jwtAcceesTokenOptions } from './jwt.constants'
@Injectable() @Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) { export class JwtStrategy extends PassportStrategy(Strategy) {
@ -9,7 +8,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
super({ super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false, ignoreExpiration: false,
secretOrKey: jwtAcceesTokenOptions.secret secretOrKey: process.env.JWT_SECRET
}) })
} }

View File

@ -21,7 +21,7 @@ export class LocalAuthGuard extends AuthGuard('local') {
if (err || !user) { if (err || !user) {
throw err || new UnauthorizedException() throw err || new UnauthorizedException()
} }
console.log(info) console.log('LocalAuthGuard.handleRequest().info =>' + info)
return user return user
} }
} }

View File

@ -12,6 +12,7 @@ export class LocalStrategy extends PassportStrategy(Strategy) {
super({ usernameField: process.env.AUTH_USERNAME_FIELD }) super({ usernameField: process.env.AUTH_USERNAME_FIELD })
} }
//Login인증용
async validate(email: string, password: string): Promise<any> { async validate(email: string, password: string): Promise<any> {
const user = await this.authService.validateUser(email, password) const user = await this.authService.validateUser(email, password)
if (!user) { if (!user) {

View File

@ -9,6 +9,7 @@ import { ROLES_KEY } from '../decorators/roles.decorator'
export class RolesGuard implements CanActivate { export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {} constructor(private reflector: Reflector) {}
//조건 검색용
canActivate( canActivate(
context: ExecutionContext context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> { ): boolean | Promise<boolean> | Observable<boolean> {
@ -16,12 +17,12 @@ export class RolesGuard implements CanActivate {
context.getHandler(), context.getHandler(),
context.getClass() context.getClass()
]) ])
//Role조건이 없는 경우
if (!requiredRoles) { if (!requiredRoles) {
return true return true
} }
//Role조건이 있는 경우 판단
const { user } = context.switchToHttp().getRequest() const { user } = context.switchToHttp().getRequest()
//console.log(requiredRoles)
//console.log(user)
return requiredRoles.some((role) => user?.roles?.includes(role)) return requiredRoles.some((role) => user?.roles?.includes(role))
//return true //return true
} }

View File

@ -4,18 +4,18 @@ import { PrismaClient } from '@prisma/client'
@Injectable() @Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit { export class PrismaService extends PrismaClient implements OnModuleInit {
[x: string]: any [x: string]: any
constructor() { // constructor() {
//SQL 로그를 출력하기위해 추가 // //SQL 로그를 출력하기위해 추가
super({ // super({
log: [ // log: [
{ emit: 'event', level: 'query' }, // { emit: 'event', level: 'query' },
{ emit: 'stdout', level: 'info' }, // { emit: 'stdout', level: 'info' },
{ emit: 'stdout', level: 'warn' }, // { emit: 'stdout', level: 'warn' },
{ emit: 'stdout', level: 'error' } // { emit: 'stdout', level: 'error' }
], // ],
errorFormat: 'colorless' // errorFormat: 'colorless'
}) // })
} // }
async onModuleInit() { async onModuleInit() {
await this.$connect() await this.$connect()
@ -24,7 +24,7 @@ export class PrismaService extends PrismaClient implements OnModuleInit {
async enableShutdownHooks(app: INestApplication) { async enableShutdownHooks(app: INestApplication) {
this.$on('beforeExit', async (event) => { this.$on('beforeExit', async (event) => {
//SQL 로그를 출력하기위해 추가 //SQL 로그를 출력하기위해 추가
console.log(event.name) //console.log(event.name)
await app.close() await app.close()
}) })
} }