1번째 수정..
This commit is contained in:
parent
ca7d09b4c2
commit
3c9cba1e86
4
.env
4
.env
@ -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
|
||||
|
||||
@ -27,6 +27,7 @@ export class AuthController {
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Get('islogin')
|
||||
getProfile(@Request() req) {
|
||||
//console.log(req)
|
||||
return req.user
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
4
src/auth/decorators/has-roles.decorator.ts
Normal file
4
src/auth/decorators/has-roles.decorator.ts
Normal 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)
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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> {
|
||||
|
||||
4
src/auth/guards/role.enum.ts
Normal file
4
src/auth/guards/role.enum.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export enum Role {
|
||||
USER = 'USER',
|
||||
ADMIN = 'ADMIN'
|
||||
}
|
||||
7
src/auth/guards/roles.guard.spec.ts
Normal file
7
src/auth/guards/roles.guard.spec.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { RolesGuard } from './roles.guard';
|
||||
|
||||
describe('RolesGuard', () => {
|
||||
it('should be defined', () => {
|
||||
expect(new RolesGuard()).toBeDefined();
|
||||
});
|
||||
});
|
||||
27
src/auth/guards/roles.guard.ts
Normal file
27
src/auth/guards/roles.guard.ts
Normal 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
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user