刷新令牌 API 错误“secretOrPrivateKey 必须有值”

tal*_*don 4 node.js jwt typescript refresh-token nestjs

当用户登录 API 时会生成一个令牌,以便他可以访问其他端点,但该令牌会在 60 秒后过期,我创建了一个函数来使用旧令牌(存储在数据库中)生成新的有效令牌,但是当我要生成新的有效令牌时,我收到 SecretOrPrivateKey 必须有一个值错误

函数refreshToken使用函数login生成一个新的token

嵌套错误:

secretOrPrivateKey must have a value
Error: secretOrPrivateKey must have a value
   at Object.module.exports [as sign] (C:\Users\talis\nova api\myflakes_api\node_modules\jsonwebtoken\sign.js:107:20)
   at JwtService.sign (C:\Users\talis\nova api\myflakes_api\node_modules\@nestjs\jwt\dist\jwt.service.js:28:20)
   at AuthService.login (C:\Users\talis\nova api\myflakes_api\src\auth\auth.service.ts:18:39)
   at TokenService.refreshToken (C:\Users\talis\nova api\myflakes_api\src\token\token.service.ts:39:37)
   at processTicksAndRejections (node:internal/process/task_queues:96:5)
   at TokenController.refreshToken (C:\Users\talis\nova api\myflakes_api\src\token\token.controller.ts:12:16)
   at C:\Users\talis\nova api\myflakes_api\node_modules\@nestjs\core\router\router-execution-context.js:46:28
   at C:\Users\talis\nova api\myflakes_api\node_modules\@nestjs\core\router\router-proxy.js:9:17
Run Code Online (Sandbox Code Playgroud)

我的代码:

token.service.ts文件中的函数refreshToken

async refreshToken(oldToken: string) {
    let objToken = await this.tokenRepository.findOne({hash: oldToken})
    if (objToken) {
        let user = await this.userService.findOneOrFail({email:objToken.email})
        return this.authService.login(user)
    } else {
        return new UnauthorizedException(MessagesHelper.TOKEN_INVALID)
    }
}
Run Code Online (Sandbox Code Playgroud)

auth.service.ts 文件中的函数登录

async login(user: UsersEntity) {
    const payload = { email: user.email, sub: user.idUser }
    const token = this.jwtService.sign(payload) // here!!!
    this.tokenService.save(token, user.email)
    return {
        token: token
    };
}
Run Code Online (Sandbox Code Playgroud)

错误已开启const token = this.jwtService.sign(payload)

这是文件 jwt.strategy.ts

import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { ExtractJwt, Strategy } from "passport-jwt";
import { jwtConstants } from "../constants";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
    constructor() {
        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            ignoreExpiration: false,
            secretOrKey: jwtConstants.secret,
        });
    }

    async validate(payload: { sub: any; email: any; }) {
        return { id: payload.sub, email: payload.email}
    }
}
Run Code Online (Sandbox Code Playgroud)

这里是 local.strategy.ts

import { Injectable, UnauthorizedException } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy } from "passport-local";
import { MessagesHelper } from "src/helpers/messages.helper";
import { AuthService } from "../auth.service";

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
    constructor(private authService: AuthService) {
        super({ usernameField: 'email' });
    }

    async validate(email: string, password: string): Promise<any> {
        const user = await this.authService.validateUser(email, password);
        if(!user) 
            throw new UnauthorizedException(MessagesHelper.PASSWORD_OR_EMAIL_INVALID)
        
        return user;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是 AuthModule,其中 JwtModule.register

@Module({
    imports: [
    ConfigModule.forRoot(),
    UsersModule,
    PassportModule,
    TokenModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
      controllers: [AuthController],
      providers: [AuthService, LocalStrategy, JwtStrategy],
      exports: [JwtModule, AuthService]
})
export class AuthModule {}
Run Code Online (Sandbox Code Playgroud)

伙计们,我尝试使用图像,但我是新用户,我仍然没有声誉,抱歉。

koh*_* 96 15

@Micael Levi在评论中提到的对我有用,所以它是:

const token = this.jwtService.sign(payload, jwtConstants.secret)
Run Code Online (Sandbox Code Playgroud)

为了将来的参考,尽管定义了我的环境变量,但我还是遇到了这个问题(未定义 process.env.SECRET_KEY 是其他类似问题中常见的问题)。所以我做的修复工作是:

return {
      access_token: this.jwtService.sign(payload, { secret: process.env.JWT_SEC }),
};
Run Code Online (Sandbox Code Playgroud)