JWT : JSON Web Token is mostly used for data encryption
Here, key is the string-type password
--> Using this key, only the one who knows the password is able to access for decoding.
// ============== Authorization Resolver ==============
@Mutation(() => String)
async login(
@Args('email') email: string, //
@Args('password') password: string,
) {
// 1. ๋ก๊ทธ์ธ (DB์์ ์ด๋ฉ์ผ๊ณผ ๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ๋ ์ ์ ์ฐพ๊ธฐ)
const user = await this.userService.findOne({ email });
// 2. ์ผ์นํ๋ ์ ์ ๊ฐ ์์ผ๋ฉด ==> ์๋ฌ ๋์ง๊ธฐ
if (!user) {
throw new UnprocessableEntityException('์กด์ฌํ์ง ์๋ ์ด๋ฉ์ผ์
๋๋ค'); // 422 error -> ๋ก์ง์์ ๋ฌธ์ ๊ฐ ์์๋
}
// 3. ์ผ์นํ๋ ์ ์ ๊ฐ ์์ง๋ง ์ํธ๊ฐ ํ๋ ธ๋ค๋ฉด ==> ์๋ฌ ๋์ง๊ธฐ
const isAuth = await bcrypt.compare(password, user.password); // ์์ ์ค์ํจ
if (!isAuth) {
throw new UnprocessableEntityException('์ํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค');
}
// 4. ์ผ์นํ๋ ์ ์ ๊ฐ ์์ผ๋ฉด ==> accessToken (JWT) ํ ํฐ ๋ง๋ค์ด์ ํ๋ก ํธ์ค๋์ ์ฃผ๊ธฐ
return this.authService.getAccessToken({ user });
}
// ============== Authentication Services ==============
@Injectable()
export class AuthService {
constructor(private readonly jwtService: JwtService) {}
getAccessToken({ user }) {
// sub์ํ๊ณ idํด๋ ๋จ - just written in jwt docs
return this.jwtService.sign(
{ email: user.email, sub: user.id },
{ secret: 'myAccessKey', expiresIn: '1h' },
);
}
}
file route - commons/auth
export class GqlAuthAccessGuard extends AuthGuard('access') {
getRequest(context: ExecutionContext) {
// ๊ฒ์ฆํ๋ ํจ์ ==> ํจ์๋ฅผ ๋ฐ๊ฟ์น๊ธฐํด์ฃผ๋๊ฑฐ์ AuthGuard('access)๋ฅผ get Request๋ก ๋ฐ๊ฟ์ค
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
}
==> gql ํ์ด๋ด๊ธฐ (=guard ๋ซ๊ธฐ)
@Injectable()
export class JwtAccessStrategy extends PassportStrategy(Strategy, 'access') {
// ์ฌ๊ธฐ ์์ฑํ๋๋ก userResolver์ fetchUser ๊ฒ์ฆํ๊ฒ ๋ค
constructor() {
super({
// ๊ฒ์ฆ๋ถ (๋จผ์ ์คํ๋๊ณ ๊ฒ์ฆ์ ์ฑ๊ณตํ๋ฉด)
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'myAccessKey',
});
}
// ๊ฒ์ฆ ์๋ฃ๋๋ฉด ์คํ (๊ฒ์ฆ ์ฑ๊ณต)
validate(payload) {
console.log(payload);
return {
email: payload.email,
id: payload.sub,
};
}
}