Node.js 在Passport.js&;JWT策略,身份验证后令牌会发生什么变化?它存储在哪里(或者我应该存储在哪里)以及如何读取?
我是认证新手 我正在使用nestJS后端和Passport&JWT策略的身份验证机制与nodeJS开发一个应用程序 这是我在github的某个repo中找到的登录控制器。 我已经实现了它,它很有效。我可以进行ajax调用、身份验证并获取令牌作为响应 auth.controller.ts:Node.js 在Passport.js&;JWT策略,身份验证后令牌会发生什么变化?它存储在哪里(或者我应该存储在哪里)以及如何读取?,node.js,express,jwt,passport.js,nestjs,Node.js,Express,Jwt,Passport.js,Nestjs,我是认证新手 我正在使用nestJS后端和Passport&JWT策略的身份验证机制与nodeJS开发一个应用程序 这是我在github的某个repo中找到的登录控制器。 我已经实现了它,它很有效。我可以进行ajax调用、身份验证并获取令牌作为响应 auth.controller.ts: import { Controller, Post, HttpStatus, HttpCode, Get, Response, Body, Param, Req, Res } from '@nestjs/co
import { Controller, Post, HttpStatus, HttpCode, Get, Response, Body, Param, Req, Res } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UserService } from '../user/user.service';
import { User } from 'user/user.entity';
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService,
private readonly userService: UserService) {}
@Post('login')
async loginUser(@Response() res: any, @Body() body: User) {
if (!(body && body.email && body.password)) {
return res.status(HttpStatus.FORBIDDEN).json({ message: 'Email and password are required!' });
}
const user = await this.userService.findOneByEmail(body.email);
if (user) {
if (await this.userService.compareHash(body.password, user.password)) {
return res.status(HttpStatus.OK).json(await this.authService.createToken(user.email));
}
}
return res.status(HttpStatus.FORBIDDEN).json({ message: 'Email or password wrong!' });
}
}
我试图理解为什么我应该将令牌返回给客户机?
我应该将令牌保存在哪里,以及如何读取它?
我知道Passport.js是一个中间件,可以处理所有这些问题,但我不知道如何处理
起初我以为我应该把它保存为一个httpOnly cookie,但现在我确定如果有必要,或者passport正在为我做类似的事情
下面是更多的代码:
auth.module.ts
import { Module, MiddlewareConsumer, forwardRef } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { UserModule } from '../user/user.module';
import { PassportModule } from '@nestjs/passport';
import { AuthController } from '../auth/auth.controller';
import { PatientModule } from '../patient/patient.module'
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secret: 'secretKey',
signOptions: {
expiresIn: 3600,
},
}),
UserModule,
PatientModule
],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
})
export class AuthModule {}
auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { JwtPayload } from './jwt-payload.interface';
import { UserService } from '../user/user.service';
@Injectable()
export class AuthService {
constructor(private readonly jwtService: JwtService, private readonly userService: UserService,) {}
async createToken(email) {
const expiresIn = 3600
const user: JwtPayload = { email:email};
const token = await this.jwtService.sign(user);
return {
token,
expiresIn: expiresIn
};
}
async validateUser(payload: JwtPayload): Promise<any> {
return await this.userService.findOneByEmail(payload.email);
}
}
从'@nestjs/common'导入{Injectable};
从'@nestjs/jwt'导入{JwtService};
从“./jwt payload.interface”导入{JwtPayload};
从“../user/user.service”导入{UserService};
@可注射()
导出类身份验证服务{
构造函数(私有只读jwtService:jwtService,私有只读userService:userService,){}
异步createToken(电子邮件){
常数expiresIn=3600
const user:JwtPayload={email:email};
const token=wait this.jwtService.sign(用户);
返回{
代币
expiresIn:expiresIn
};
}
异步validateUser(有效负载:JwtPayload):承诺,但没有任何结果。您使用的是jsonwebtokens,因此不必在后端执行任何操作。基本上,当用户登录并将该令牌传递给前端时,您会生成令牌。您不必将其存储在数据库或任何东西中,因为令牌的结构使您可以在拥有se的情况下对其进行解码cret.只需确保通过添加头Authorization:Bearer{your_token}将它传递到所有请求的后端
@DylanAspden我要问的是,我已经登录,创建了一个令牌,将其作为响应发送给客户端,但没有做任何处理。现在我想向受authGuard或其他保护的服务器发出请求,我必须对该请求进行身份验证,服务器需要通过令牌检查我是谁。服务器将在哪里从中获取令牌?正如您所说,我需要在请求的标题中传递该令牌,但要做到这一点,我必须在登录时收到该令牌后将其保存在某个位置,如果我没有弄错的话。您的服务器已经在处理在您的JwtStrategy
类中获取该令牌的操作。它会处理所有事情,然后将您的用户实例加载到request.user
。如果您想访问request.user
您可以为此创建一个装饰器。您可以将令牌存储在前端的本地存储中,这通常就足够了。您也可以将令牌存储在cookie中。@dylanaspen ok,那么如果JwtStrategy
类正在处理所有事情,我为什么要存储t如果我不需要发送,请在前端使用帽子令牌?您可以在前端使用两种存储方式,一种是本地存储(简易),另一种是将httpOnly
设置为true
(需要更多工作)。如果您将令牌存储在本地存储中,您的代码将立即生效。有些人正确地认为本地存储不太安全,因此我们倾向于使用cookie解决方案。但您最了解您的项目,因此可以做出此决定。您使用的是jsonwebtokens,因此不必在后端执行任何操作。基本上当用户登录时,您生成令牌并将该令牌传递到前端。您不必将其存储在数据库或任何东西中,因为令牌的结构使您可以在拥有秘密的情况下对其进行解码。只需确保通过添加头Authorization:Bearer{your_token}将其传递到所有请求的后端即可
@DylanAspden我要问的是,我已经登录,创建了一个令牌,将其作为响应发送给客户端,但没有做任何处理。现在我想向受authGuard或其他保护的服务器发出请求,我必须对该请求进行身份验证,服务器需要通过令牌检查我是谁。服务器将在哪里从中获取令牌?正如您所说,我需要在请求的标题中传递该令牌,但要做到这一点,我必须在登录时收到该令牌后将其保存在某个位置,如果我没有弄错的话。您的服务器已经在处理在您的JwtStrategy
类中获取该令牌的操作。它会处理所有事情,然后将您的用户实例加载到request.user
。如果您想访问request.user
您可以为此创建一个装饰器。您可以将令牌存储在前端的本地存储中,这通常就足够了。您也可以将令牌存储在cookie中。@dylanaspen ok,那么如果JwtStrategy
类正在处理所有事情,我为什么要存储t如果我不需要发送,请在前端使用帽子令牌?您可以在前端使用两种存储方式,一种是本地存储(简易),另一种是将httpOnly
设置为true
(需要更多工作)。如果您将令牌存储在本地存储中,您的代码将立即生效。有些人正确地认为本地存储不太安全,因此我们倾向于使用cookie解决方案。但您知道您的项目最好做出此决定。
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthService } from './auth.service';
import { JwtPayload } from './jwt-payload.interface';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'secretKey',
});
}
async validate(payload: JwtPayload): Promise<boolean> {
const user = await this.authService.validateUser(payload);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}