Tom*_*wik 7 javascript node.js jwt typescript nestjs
我正在尝试根据尝试登录的用户的秘密创建用户令牌。但是,我想使用分配给数据库内用户对象的秘密,而不是使用环境中的秘密。
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UserService } from '@src/modules/user/services';
@Injectable()
export class AuthService {
public constructor(private readonly jwtService: JwtService,
private readonly userService: UserService) {}
public async createToken(email: string): Promise<JwtReply> {
const expiresIn = 60 * 60 * 24;
const user = await this.userService.user({ where: { email } });
const accessToken = await this.jwtService.signAsync({ email: user.email },
/* user.secret ,*/
{ expiresIn });
return {
accessToken,
expiresIn,
};
}
}
Run Code Online (Sandbox Code Playgroud)
我是 Nestjs 的新手,也许我错过了一些东西。
node-jsonwebtoken确实在sign(...)函数中提供了必要的参数。nestjs/jwt缺少这个参数(见代码)。您将如何在不使用node-jsonwebtoken或更抽象的问题的情况下解决它:我处理用户机密的方式在这里有意义吗?谢谢。
仅使用 nest 还无法做到这一点,JwtModule但您可以轻松地自己实现缺失的部分。
您可以通过调用以下路由来创建令牌:
user1(秘密:'123'):https:
//yw7wz99zv1.sse.codesandbox.io/login/1 user2(秘密:'456'):https : //yw7wz99zv1.sse.codesandbox.io/login/2
然后'/'使用您的令牌调用受保护的路由并接收您的用户:
curl -X GET https://yw7wz99zv1.sse.codesandbox.io/ \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxIiwiaWF0IjoxNTUzNjQwMjc5fQ.E5o3djesqWVHNGe-Hi3KODp0aTiQU9X_H3Murht1R5U'
Run Code Online (Sandbox Code Playgroud)
在AuthService我只是使用标准jsonwebtoken库来创建令牌。然后,您可以createToken从登录路由调用:
import * as jwt from 'jsonwebtoken';
export class AuthService {
constructor(private readonly userService: UserService) {}
createToken(userId: string) {
const user = this.userService.getUser(userId);
return jwt.sign({ userId: user.userId }, user.secret, { expiresIn: 3600 });
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
在JwtStrategy您使用secretOrKeyProvider而不是secretOrKey它可以异步访问UserService以动态获取用户机密:
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private readonly authService: AuthService,
private readonly userService: UserService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKeyProvider: (request, jwtToken, done) => {
const decodedToken: any = jwt.decode(jwtToken);
const user = this.userService.getUser(decodedToken.userId);
done(null, user.secret);
},
});
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
请注意,您传递给JwtModulelike的选项expiresIn不会被使用,而是直接在AuthService. JwtModule不带任何选项导入:
JwtModule.register({})
Run Code Online (Sandbox Code Playgroud)
我处理用户机密的方式在这里有意义吗?
如果不知道您的确切要求,就很难回答这个问题。我想 jwt 有一些用例具有动态秘密,但是有了它,您将失去 jwt 的一个重要属性:它们是无状态的。这意味着您AuthService可以发出 jwt 令牌,而一些ProductService需要身份验证的令牌可以只信任 jwt(它知道秘密),而无需调用其他服务(即UserService必须查询数据库)。
如果与用户相关的密钥不是硬性要求,请考虑使用 jwt 的kid属性频繁轮换密钥。
| 归档时间: |
|
| 查看次数: |
2234 次 |
| 最近记录: |