【问题标题】:NestJS Authentification with JWT Passport not working使用 JWT Passport 的 NestJS 身份验证不起作用
【发布时间】:2020-01-25 20:13:10
【问题描述】:

我正在尝试使用带有nestjs 的jwt-passport 设置一个非常简单的登录系统。我遵循了本教程:https://docs.nestjs.com/techniques/authentication,但我无法让它工作。我对这些东西真的很陌生,如果有人能给我指路,我将不胜感激。

我发送登录到服务器的方式:

    this.clientAuthService.login(this.userName, this.password).then(response => {
        this.clientAuthService.setToken(response.access_token);
        this.router.navigate(['/backend']);
    });

我的客户身份验证服务:

export class ClientAuthService {

  constructor(private http: HttpClient, @Inject(PLATFORM_ID) private platformId) {
  }

  getToken(): string {
    if (isPlatformBrowser(this.platformId)) {
      return localStorage.getItem(TOKEN_NAME);
    } else {
      return '';
    }
  }

  setToken(token: string): void {
    if (isPlatformBrowser(this.platformId)) {
      localStorage.setItem(TOKEN_NAME, token);
    }
  }

  removeToken() {
    if (isPlatformBrowser(this.platformId)) {
      localStorage.removeItem(TOKEN_NAME);
    }
  }

  getTokenExpirationDate(token: string): Date {
    const decoded = jwt_decode(token);

    if (decoded.exp === undefined) {
      return null;
    }

    const date = new Date(0);
    date.setUTCSeconds(decoded.exp);
    return date;
  }

  isTokenExpired(token?: string): boolean {
    if (!token) {
      token = this.getToken();
    }
    if (!token) {
      return true;
    }

    const date = this.getTokenExpirationDate(token);
    if (date === undefined) {
      return false;
    }
    return !(date.valueOf() > new Date().valueOf());
  }

  login(userName: string, password: string): Promise<any> {
    const loginData = {username: userName, password};
    return this.http
      .post(Constants.hdaApiUrl + 'user/login', loginData, {headers: new HttpHeaders({'Content-Type': 'application/json'})})
      .toPromise();
  }

}

我的 user.controller.ts

@Controller('user')
export class UserController {

  constructor(private readonly authService: AuthService) {
  }

  @UseGuards(AuthGuard('local'))
  @Post('login')
  authenticate(@Request() req) {
    return this.authService.login(req);
  }

}

我的 user.service.ts

export class UsersService {
  private readonly users: User[];

  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'test',
        password: '12345',
      }
    ];
  }

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}

然后我有 jwt.strategy.ts

export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: Constants.jwtSecret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}

和 local.strategy.ts

export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

主要是我只是按照教程自己为客户端添加了一些东西。 我错过了登录路径的UseGuard('local') 部分,但是在我添加它之后,我总是收到 401 错误。 当我不使用UseGuard('local') 时,我在登录表单中输入的内容并不重要。提交详细信息后,即使不正确,我也可以访问后端。

另外,值得一提的是,jwt.strategy.ts 和 local.strategy.ts 中的验证方法在 WebStorm 中被标记为 not used

我知道这里有很多代码,但我需要帮助,因为我找不到任何其他最新的 NestJS 身份验证配置来源。感觉就像我遵循的教程错过了很多初学者的步骤。

【问题讨论】:

    标签: node.js angular jwt nestjs passport-local


    【解决方案1】:

    确保您的帖子正文(有效负载)与验证方法的签名相同(实际上必须是用户名和密码)。

    【讨论】:

    • 非常感谢您的回复。我仍然不知道问题出在哪里,但我创建了一个新项目并完全按照教程进行操作,现在它可以工作了。在我没有像教程中提到的那样创建单独的模块之前。也许这就是问题所在。
    • 谢谢。我希望他们会在他们的文档中提到它。
    【解决方案2】:

    为了添加更多上下文,在上图中,您可以找到详细信息,其中提到了指定签名的实现。因此,必须在正文中发送准确的“用户名”和“密码”属性。

    注意:如果您想自定义本地策略服务的签名,您只需在 super() 中传递一个新对象以指定新属性:

    constructor() {
      super({ usernameField: 'email' });
    }
    

    参考:https://docs.nestjs.com/techniques/authentication

    【讨论】:

      【解决方案3】:

      对我来说,在多个项目中,

      使用

      export class JwtStrategy extends PassportStrategy(Strategy, 'theJwt')
      

      @UseGuards(AuthGuard('theJwt'))

      而不是使用:

      export class JwtStrategy extends PassportStrategy(Strategy)
      

      @UseGuards(AuthGuard(JwtStrategy )),这不起作用。

      【讨论】:

        猜你喜欢
        • 2019-03-28
        • 2019-06-29
        • 2019-10-04
        • 2017-05-13
        • 2016-01-02
        • 1970-01-01
        • 2015-01-02
        • 1970-01-01
        • 2019-06-06
        相关资源
        最近更新 更多