(1) 가드란?
가드는 함수다. 클라이언트에서 온 Request를 더 진행할지, 말지 결정할 수 있는 함수다. @Injectable 할수 있다. 즉 Provider
다. 그리고 CanActivate
를 implements
한다.
CanActivate
의 역할은 가드에서 true를 return 하면, request를 진행시키고 false를 return 하면 request를 멈추게 한다.
현재 챕터에서 가드를 사용하는 이유가 뭘까?
전 챕터에서 Resolver
레이어에서 gql context
를 통해 request가 발생할 때 유저의 정보를 받아 처리했다. (어떤 처리? : client에서 token을 보내고 해당 토큰의 유저 정보를 db에서 조회하는 과정) 하지만 Resolver
에 로직이 있는 것은 별로 좋지 못한 모양새인듯하다. 그래서 이것을 Resolver
전 레이어에서 처리하기 위해 가드(미들웨어인 것 같다)를 생성하고, 가드에서 분기 로직을 처리한다. 가드에서 true를 return 하면 request가 계속 진행되고, false를 return 하면 request가 멈춘다.
(2) 가드 생성하기
auth 모듈안에서 auth.guard.ts
로 생성한다.
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext) {
console.log(context);
return false; // canActivate()는 boolean을 return 해야 한다.
}
}
ExecutionContext: request의 context에 접근할 수 있게 해주는 것. 참고로 graphql의 context가 아니라 현재 pipline의 context다.
(3) 생성한 가드 사용하기
AuthGuard를 생성하고 이것을 사용하려면, Resolver
에서 사용한다.
@Query(() => User)
@UseGuards(AuthGuard) // @UserGuard안에 생성한 가드를 넣어준다.
me() {}
(4) query 요청해보기
{
me {
eamil
}
}
query를 요청하면, 가드에서 표시한 context가 표시된다. 다만 현재 context는 http context이기때문에 gql context로 변경해야 한다고 한다. 그리고 변경한 gql guard에서 user정보를 꺼내서 user 정보의 유무에 따라 각각 boolean을 return 한다.
// http context -> gql context로 변경
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context).getContext();
const user = gqlContext['user'];
if (!user) {
return false;
} else {
return true;
}
}
}
@Query(() => User)
@UseGuards(AuthGuard)
me(@Context() context) {
return true;
}
Resolver 에서 @Query 부분에서 User를 넣으면 아래와 같이 에러가 발생했다. 에러가 발생한 원인은 Entity에서 @OnjectType을 넣어주지 않아서 발생한 것이었다. 이유는 좀 더 알아봐야겠다.