1번째 수정..

This commit is contained in:
최준흠 2022-08-18 17:55:17 +09:00
parent ca7d09b4c2
commit 3c9cba1e86
10 changed files with 67 additions and 5 deletions

4
.env
View File

@ -6,6 +6,8 @@
DATABASE_URL="mysql://root:@localhost:3306/test"
JWT_SECURITY_KEY = "security_key"
JWT_EXPIRE_MAX = "60s"
JWT_EXPIRE_MAX = "600s"
AUTH_USERNAME_FIELD="email"
DEFAULT_TABLE_PER_PAGE = 20
DEFAULT_TABLE_PAGE = 0

View File

@ -27,6 +27,7 @@ export class AuthController {
@UseGuards(JwtAuthGuard)
@Get('islogin')
getProfile(@Request() req) {
//console.log(req)
return req.user
}
}

View File

@ -15,18 +15,21 @@ export class AuthService {
if (user && user.password === password) {
const { password, ...result } = user
// result는 password 를 제외한 user의 모든 정보를 포함한다.
//console.log(result)
return result
}
return null
}
async login(user: any) {
//console.log(user)
const payload = {
id: user.id,
email: user.email,
name: user.name,
role: user.role
roles: [user.role]
}
// console.log(payload)
return { access_token: this.jwtService.sign(payload) }
}
}

View File

@ -0,0 +1,4 @@
import { SetMetadata } from '@nestjs/common'
import { Role } from '../guards/role.enum'
export const HasRoles = (...roles: Role[]) => SetMetadata('has-roles', roles)

View File

@ -18,7 +18,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
id: payload.id,
email: payload.email,
name: payload.name,
role: payload.role
roles: payload.roles
}
}
}

View File

@ -2,13 +2,14 @@ import { Strategy } from 'passport-local'
import { PassportStrategy } from '@nestjs/passport'
import { Injectable, UnauthorizedException } from '@nestjs/common'
import { AuthService } from 'src/auth/auth.service'
import { env } from 'process'
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
//super()
//If you want to check user authenticate with custom column like 'email', try pass it.
super({ usernameField: 'email' })
super({ usernameField: env.AUTH_USERNAME_FIELD })
}
async validate(email: string, password: string): Promise<any> {

View File

@ -0,0 +1,4 @@
export enum Role {
USER = 'USER',
ADMIN = 'ADMIN'
}

View File

@ -0,0 +1,7 @@
import { RolesGuard } from './roles.guard';
describe('RolesGuard', () => {
it('should be defined', () => {
expect(new RolesGuard()).toBeDefined();
});
});

View File

@ -0,0 +1,27 @@
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { Observable } from 'rxjs'
import { Role } from './role.enum'
//참고: https://shpota.com/2022/07/16/role-based-authorization-with-jwt-using-nestjs.html
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(
context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(
'has-roles',
[context.getHandler(), context.getClass()]
)
if (!requiredRoles) {
return true
}
const { user } = context.switchToHttp().getRequest()
//console.log(requiredRoles)
//console.log(user)
return requiredRoles.some((role) => user?.roles?.includes(role))
//return true
}
}

View File

@ -6,10 +6,15 @@ import {
Param,
Post,
Put,
Query
Query,
UseGuards
} from '@nestjs/common'
import { Todo } from '@prisma/client'
import { env } from 'process'
import { HasRoles } from 'src/auth/decorators/has-roles.decorator'
import { JwtAuthGuard } from 'src/auth/guards/jwt.authguard'
import { Role } from 'src/auth/guards/role.enum'
import { RolesGuard } from 'src/auth/guards/roles.guard'
import { TodoDTO } from './dtos/todo.dto'
import { TodoService } from './todo.service'
@ -47,21 +52,29 @@ export class TodoController {
return this.todoService.fetchAll(sql)
}
@HasRoles(Role.USER)
@UseGuards(JwtAuthGuard, RolesGuard)
@Get(':id')
async fetchOne(@Param('id') id: number): Promise<Todo | undefined> {
return this.todoService.fetchOne(id)
}
@HasRoles(Role.USER)
@UseGuards(JwtAuthGuard, RolesGuard)
@Delete(':id')
async delete(@Param('id') id: number): Promise<Todo | undefined> {
return this.todoService.remove(id)
}
@HasRoles(Role.USER)
@UseGuards(JwtAuthGuard, RolesGuard)
@Post()
async add(@Body() data: Todo): Promise<Todo> {
return this.todoService.add(data)
}
@HasRoles(Role.USER)
@UseGuards(JwtAuthGuard, RolesGuard)
@Put(':id')
async update(@Param('id') id: number, @Body() data: TodoDTO): Promise<Todo> {
return this.todoService.update(id, data)