1

我正在尝试为任务应用程序实现 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

4

2 回答 2

3

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

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

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

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

于 2020-01-02T13:51:15.380 回答
2

您尝试做的事情非常罕见,仅供参考。

通常,您只需删除用户的LocalStorage.

您可以跳过一些障碍并将令牌列入黑名单,但这对于大多数情况下不必要的事情来说是很多工作。如果您想要额外的安全性,请为令牌选择更短的到期时间。

于 2020-06-15T19:28:04.997 回答