기존 REST API를 기준으로 만들던 서버에서도 토큰 검증을 담당하는 기능은 재사용성을 위해 미들웨어로 만들었었다.
그래서 이번 프로젝트에서도 토큰 검증을 담당하는 기능을 미들웨어로 만들고자 하였다. 찾아보니 Type Graphql에도 middleware를 사용할 수 있도록 설계가 되어 있어서 개발을 진행했다.
다만, request를 직접 전달받는 게 아닌 GraphQL의 특성 상 전달할 때 HTTP Header에 전달된 내용을 파싱하는 것부터 알아봐야 했다.
공식 문서를 찾아보니 위와 같이 전달된 request에 접근할 수 있는 것으로 보아 headers에도 접근할 수 있는 것 같아 다음과 같이 코드를 작성했다.
new ApolloServer({
schema,
context: ({ req }) => {
context.token = req.headers.authorization || "";
return context;
},
// 생략
});
이렇게 하니 실제로 context
인스턴스에 token 값이 담겨 전달되는 것을 확인할 수 있었다.
import { verify } from "jsonwebtoken";
import { MiddlewareFn } from "type-graphql";
import { context } from "../context";
import config from "../config";
import { Unauthorized } from "../dto";
export const auth: MiddlewareFn = async (_, next) => {
const token: string = context.token;
if (!token) {
return new Unauthorized();
}
const bearer: string = token.split("Bearer ")[1];
verify(bearer, config.JWT_SECRET, (err, decoded) => {
if (err || !decoded) {
return new Unauthorized();
}
context.decoded = decoded;
});
return await next();
};
기존 Express와는 다르게 Type Graphql의 미들웨어는 next() 호출시 해당 미들웨어 다음에 있는 함수(또 다른 미들웨어나 resolver)를 실행시키고 그 결과를 받는 실행 함수느낌이다.
실제 공식 문서에도 Express보다는 Koa와 비슷하다고 한다.