Как заставить работать запрос токена NestJS JWT?
Я создаю этот API, используя JWT и NestJS. Это API для мобильного приложения, поэтому мне нужно, чтобы токен JWT постоянно обновлялся. Идея состоит в том, чтобы проверить входящий запрос токена, если срок действия токена истек, JWT выдаст сообщение об ошибке, говорящее, что токен истек. Если это так, токен будет обновлен, если это другая ошибка, он выдаст ошибку.
У меня также есть декоратор GetUser, который возвращал бы пользователя из HttpRequest, но теперь, когда я использую собственный AuthGuard, я не могу заставить его работать. Какие-нибудь советы?
AuthGuard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { LoginService } from 'src/users/login.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private loginService: LoginService,
private jwtService: JwtService
) {}
async canActivate( context: ExecutionContext ) {
const request = context.switchToHttp().getRequest();
const { headers } = request;
const headerString = headers.authorization.split(' ');
const currentToken = await this.loginService.validateToken(headerString[1]);
return currentToken ? true : false;
}
}
LoginService.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService, JwtSignOptions } from '@nestjs/jwt';
@Injectable()
export class LoginService {
constructor(
private jwtService: JwtService
) { }
async validateToken(token: string): Promise<any> {
try {
const verifiedToken = await this.jwtService.verify(token, { secret: process.env.JWT_SECRET });
return verifiedToken;
} catch (error) {
if (error.message === 'jwt expired' ) {
const newToken = await this.refreshToken(token);
return newToken;
} else {
throw new UnauthorizedException();
}
}
}
async refreshToken(token: string | any ): Promise<any> {
const decodedToken = await this.jwtService.decode(token) as any;
const { email, id } = decodedToken;;
const payload = { email, id };
const options: JwtSignOptions = {
secret: process.env.JWT_SECRET,
expiresIn: '2w'
};
const accessToken = await this.jwtService.sign(payload, options);
return { accessToken };
}
}
userDecorator.ts
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
import { User } from "./user.entity";
export const GetUser = createParamDecorator( (data, ctx: ExecutionContext): User => {
const req = ctx.switchToHttp().getRequest();
return req.user;
});
Любая помощь будет оценена! благодаря
1 ответ
Если токен действителен, декодируйте токен и добавьте полезные данные пользователя к объекту запроса в методе canActivate перед отправкой true или false. Декоратор GetUser получает объект пользователя из запроса.
Пример:
// AuthGuard.ts
async canActivate( context: ExecutionContext ) {
....
....
request.user = currenToken // decoded token returns payload anyway
return true
}
Вам не нужно возвращать false, так как если токен недействителен, будет выдана несанкционированная ошибка, и фильтр исключений позаботится об этом