Node.js 在Passport.js&;JWT策略,身份验证后令牌会发生什么变化?它存储在哪里(或者我应该存储在哪里)以及如何读取?

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

我是认证新手

我正在使用nestJS后端和Passport&JWT策略的身份验证机制与nodeJS开发一个应用程序

这是我在github的某个repo中找到的登录控制器。 我已经实现了它,它很有效。我可以进行ajax调用、身份验证并获取令牌作为响应

auth.controller.ts:


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;
  }
}