들어가기
resolver(Query, mutation)을 실행시키기 전에
Guard를 셋팅하면, resolver실행 전에,
Authorization을 확인가능하다.
https://docs.nestjs.com/guards
authentication: 토큰의 유효성 확인
authorization: 유저가 어떤일을 하기 전에 할 수 있는 권한이 있는지를 확인.
$nest g mo muth
AuthGuard
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
@Injectable() ///class type은 Injectable()으로한다.
export class AuthGuard implements CanActivate {
///CanActivate는 이후로 할수 있게 할건지, 할수 없게 할건지를
///만들어 주는것, 아래 canActivate도 마찬가지
canActivate(context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context).getContext();
///http에 담겨진 context를 grapqhQL context로 옮겨주는 과정
const user = gqlContext['user'];
///grapqhQL context에서 user를 뽑아주고, 아래에서
///user가 있으면, 이후로 할 수 있게, 없으면, 이후의 것을 할 수 없게함.
if (!user) {
return false;
}
return true;
}
}
@UseGuards(AuthGuard) ///맨위에 @UseGuards(사용할 가드) 끝. 사용은 무지 쉬움,
@Query(() => UserProfileOutput)
async userProfile(
@Args() userProfileInput: UserProfileInput,
): Promise<UserProfileOutput> {
try {
const user = await this.usersService.findById(userProfileInput.userId);
if (!user) {
throw Error();
}
return {
ok: true,
user,
};
} catch (e) {
return {
error: 'User not found',
ok: false,
};
}
apollo에서 처럼 loggedInUSer를 확인해 주고 return해 줌.
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
export const AuthUser = createParamDecorator(
(data: unknown, context: ExecutionContext) => {
///위에 형식은 그대로 따라갈 것!
const gqlContext = GqlExecutionContext.create(context).getContext();
///AuthGuard와 거의 비슷, http req의 context를 grapqhql context로 만들어줌.
const user = gqlContext['user'];
return user; ///마지막에 graphql context에 담긴 user를 return해줌.
},
);
@UseGuards(AuthGuard) ///context에 user가 있는지 확인하고 다음으로 보내줌!!
@Mutation(() => EditProfileOutput)
async editProfile(
@AuthUser() authUser: User,
@Args('input') editProfileInput: EditProfileInput,
): Promise<EditProfileOutput> {
///auth-user.decorator.ts에서 만든 AuthUser를 불러줌(@AuthUser)로~
///이 과정을 통해서, loggedInUset를 확인 가능함. 그래서 editProfile 가능하게
try {
await this.usersService.editProfile(authUser.id, editProfileInput);
return {
ok: true,
};
} catch (error) {
return {
ok: false,
error,
};
}
}
AuthGuard와 AuthUser Decorator를 통해서, loggedInUser들만,
이어서 나오는 resolver들이 실행가능해지게 쉴드를 쳐 놓음.
resolver는 graphql이기 떄문에 context를 graphql context로 옮겨주는부분
확실히 인지할것!!
http, header에 있는 middleware 과정을 통해 token을 verify해서
user를 찾아주는 과정을 함. 찾은 user를 graphql의 context에 담아 주어야
모든 resolver에 적용시킬 수 있음.