首页 > 解决方案 > 使用nestjs进行身份验证,使用JWT策略的护照

问题描述

我正在尝试为任务应用程序实现 nestjs 身份验证和授权

我正在使用带有护照的 JWT 策略

但我无法实现注销方法

我试过了

@Get('/logout')
logout(@Request() req) {
    req.logout();
}

它返回 200 但我仍然可以使用令牌为刚刚注销的同一用户获取数据

我的 jwt 策略文件

import { Injectable, UnauthorizedException } from "@nestjs/common";
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { InjectRepository } from "@nestjs/typeorm";
import { UserRepository } from "./user.repository";
import { JwtPayload } from "./jwt-payload.interface";
import * as config from 'config';

const jwtConfig = config.get('jwt');

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {

    constructor(@InjectRepository(UserRepository) private userRepository: UserRepository) {
        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            secretOrKey: process.env.JWT_SECRET || jwtConfig.secret
        })
    }

    async validate(payload: JwtPayload) {
        const {username} = payload;
        const user = await this.userRepository.findOne({username});

        if(!user) {
            throw new UnauthorizedException();
        }

        return user;
    }

}

在tasks.controller中我像这样使用它

@Controller('tasks')
@UseGuards(AuthGuard('jwt'))

我的 auth.module.ts

import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './jwt.strategy';
import * as config from 'config';

const jwtConfig = config.get('jwt');

@Module({
    imports: [
        PassportModule.register({defaultStrategy: 'jwt'}),
        JwtModule.register({
            secret: process.env.JWT_SECRET || jwtConfig.secret,
            signOptions: {
                expiresIn: jwtConfig.expiresIn
            }
        }),
        TypeOrmModule.forFeature([UserRepository])
    ],
    controllers: [AuthController],
    providers: [
        AuthService,
        JwtStrategy
    ],
    exports: [
        JwtStrategy,
        PassportModule
    ]
})
export class AuthModule { }

我希望能够注销用户并且令牌应该无效并返回 401

标签: typescriptjwtnestjsnestjs-passportnestjs-jwt

解决方案


仅注销用户不会使 JWT 令牌无效(除非令牌已过期)。

为了确保令牌在注销后无效,您需要应用一些额外的策略。一种常见的方法是将令牌列入黑名单并维护列入黑名单的令牌列表。

为此,在注销时,您可以将令牌添加到黑名单并将其添加到 blacklisted-tokens 列表中。在身份验证中,您可以添加检查令牌是否被列入黑名单并相应地抛出错误。

检查此答案以获取有关处理此问题的更多想法:https ://stackoverflow.com/a/23089839/1906361


推荐阅读