Это пока невозможно только с помощью гнезда JwtModule
, но вы можете легко реализовать недостающие части самостоятельно.
Live Demo
Вы можете создавать токены, вызывая следующие маршруты:
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'
Как это работает?
В 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 });
}
// ...
}
В 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);
},
});
}
// ...
}
Обратите внимание, что параметры, которые вы передаете JwtModule
, например expiresIn
, не будут использоваться, вместо этого они будут напрямую передаваться в AuthService
. Импортируйте JwtModule
без параметров:
JwtModule.register({})
Общее
Имеет ли смысл мой способ обработки секрета пользователя?
Трудно ответить, не зная ваших точных требований. Я предполагаю, что есть варианты использования jwt с динамическими секретами, но с этим вы теряете большое свойство jwt: они не сохраняют состояния. Это означает, что ваш AuthService
может выдать токен jwt, а некоторые ProductService
, требующие аутентификации, могут просто доверять jwt (он знает секрет) без каких-либо вызовов других служб (например, UserService
, который должен запрашивать базу данных). .
Если пользовательские ключи не являются жестким требованием, рассмотрите возможность их частого вращения, используя свойство kid
jwt.