【问题标题】:NestJS jwt-passport AuthenticationNestJS jwt-passport 身份验证
【发布时间】:2019-03-28 21:23:05
【问题描述】:

我想实现一个分布式身份验证库以在多个项目中使用它。该库应实现 JWT 身份验证方法。代码如下:

jwt.strategy.ts

import {ExtractJwt, Strategy} from 'passport-jwt';
import {PassportStrategy} from '@nestjs/passport';
import {Injectable} from '@nestjs/common';
import {JwtPayload, User} from './interfaces';
import {ConfigService} from "./config.service";

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
  constructor(private readonly configService: ConfigService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: configService.get('secretOrPrivateKey'),
    });
  }

  async validate(payload: JwtPayload): Promise<User> {
     return {
      uuid: payload.uuid,
      email: payload.email,
    }
  }
}

jwt.auth.module.ts:

import {Module, DynamicModule} from '@nestjs/common';
import {JwtModule} from '@nestjs/jwt';
import {JwtStrategy} from './jwt.strategy';
import {PassportModule} from '@nestjs/passport';
import {ConfigService} from "./config.service";
import {JwtOptions} from "./interfaces/jwt.options";

@Module({
})

export class JwtAuthModule {
  static forRoot(jwtOptions): DynamicModule {
    return {
      module: JwtAuthModule,
      imports: [
        // JwtModule.register(jwtOptions),
        // PassportModule.register({defaultStrategy: 'jwt'}),
      ],
      providers: [
        JwtStrategy,
        {
          provide: ConfigService,
          useValue: new ConfigService(jwtOptions),
        }
      ],
      exports: [ConfigService, JwtStrategy]
    };
  }
}

我已经在我的app.module.ts 中导入了这个:

import { Module, NestModule, HttpModule } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { environment } from './environments';
import { AuthModule } from './auth/auth.module';
import { PermissionModule } from './permission/permission.module';
import {JwtAuthModule} from '@pe/nest-kit';
import {JwtModule} from '@nestjs/jwt';
import {PassportModule} from '@nestjs/passport';

@Module({
  imports: [
    JwtModule.register(environment.jwtOptions),
    PassportModule.register({defaultStrategy: 'jwt'}),
    JwtAuthModule.forRoot(environment.jwtOptions),
    HttpModule,
    AuthModule,
    PermissionModule,
    MongooseModule.forRoot(environment.mongodb),
  ],
})
export class ApplicationModule implements NestModule {
  configure() {
  }
}

但是,每次我尝试打开项目 url 时,都会出现错误:

[Nest] 27645 - 24.10.2018, 15:23:26 [ExceptionsHandler] 未知 身份验证策略“jwt”+4119ms 错误:未知身份验证 策略“jwt” 尝试(/home/user/workspace/permissions/node_modules/passport/lib/middleware/authenticate.js:187:37) 在进行身份验证(/home/user/workspace/permissions/node_modules/passport/lib/middleware/authenticate.js:363:7) 在 Promise (/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:83:3) 在新的承诺 () 在/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:75:83 在 MixinAuthGuard。 (/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:47:36) 在 Generator.next () 在/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:19:71 在新的承诺 () 在 __awaiter (/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:15:12) 在 MixinAuthGuard.canActivate (/home/user/workspace/permissions/node_modules/@nestjs/passport/dist/auth.guard.js:40:20) 在 GuardsConsumer.tryActivate (/home/user/workspace/permissions/node_modules/@nestjs/core/guards/guards-consumer.js:13:34) 在 canActivateFn (/home/user/workspace/permissions/node_modules/@nestjs/core/router/router-execution-context.js:97:59) 在 /home/user/workspace/permissions/node_modules/@nestjs/core/router/router-execution-context.js:47:37 在 /home/user/workspace/permissions/node_modules/@nestjs/core/router/router-proxy.js:8:23 在 Layer.handle [as handle_request] (/home/user/workspace/permissions/node_modules/express/lib/router/layer.js:95:5)

我做错了什么?

【问题讨论】:

    标签: authentication jwt nestjs nestjs-passport nestjs-jwt


    【解决方案1】:

    请在您的模块中添加 JwtStrategy 作为提供者

    @Module({
       imports: [...],
       providers: [JwtStrategy],
    })
    

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

    【讨论】:

      【解决方案2】:

      我通过安装@types/passport 解决了这个问题。使用 NestJS、TypeScript 和 JWT。

      【讨论】:

        【解决方案3】:

        尝试在您的模块中添加JwtStrategy 作为提供者:

        @Module({
          imports: [
           ....
          ],
          providers: [JwtStrategy],
        })
        

        再试一次!

        【讨论】:

          【解决方案4】:

          解决了。 在 PHP 中,我们为整个项目创建了一棵依赖树。在 npm 中,每个包都有自己的依赖子树,例如。 g.:
          --护照
          --@pe/nest-kit
          ----护照
          nest-kit 使用来自----passport 的对象,但根项目使用同名类型的对象,但实际上这是 nodejs 编译器的另一种类型。解决办法是通过@pe/nest-kit从@nestjs/passport重新导出AuthGuard,就可以了。

          【讨论】:

            【解决方案5】:

            这是我在 github 中的代码:https://github.com/riadhriadh/prototype_nestjs/tree/dev

            在 jwt.strategy.ts 中

                import * as passport from 'passport';
                import { ExtractJwt, Strategy } from 'passport-jwt';
                import { Injectable } from '@nestjs/common';
                import { AuthService } from '../auth.service';
                const  config_projet =require("./projet_config");
                @Injectable()
                export class JwtStrategy extends Strategy {
                  constructor(private readonly authService: AuthService) {
                    super(
                      {
                        jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
                        passReqToCallback: true,
                        secretOrKey: config_projet.secret,
                      },
                      async (req, payload, next) => await this.verify(req, payload, next)
                    );
                    passport.use(this);
                  }
            
                  public async verify(req, payload, done) {
                    const isValid = await this.authService.validateUser(payload);
                    if (!isValid) {
                      return done('Unauthorized', false);
                    }
                    done(null, payload);
                  }
            }
            

            ====================

            在:auth.service.ts

            import { Injectable } from '@nestjs/common';
            import * as jwt from 'jsonwebtoken';
            import { UsersService } from 'users/users.service';
            const  config_projet =require("../projet_config");
            var fs = require('fs');
            @Injectable()
            export class AuthService {
            
              constructor(private readonly usersService: UsersService) { }
            
            
              async createToken(email: string) {
                const expiresIn = 6000 * 60;
                const secretOrKey = fs.readFileSync("./key.pem");;
                const user = { email };
            
                 const token = jwt.sign(user, secretOrKey,   { audience: 'urn:foo' });
            
            
                return { expires_in: expiresIn, token };
              }
              async validateUser(signedUser): Promise<boolean> {
                if (signedUser && signedUser.email) {
                  return Boolean(this.usersService.getUserByEmail(signedUser.email));
                }
            
                return false;
              }
            }
            

            ===============================

            在:auth.controller.ts

            =================================

            import { Controller, Post, HttpStatus, HttpCode, Get, Response, Body } from '@nestjs/common';
            import { AuthService } from './auth.service';
            import { UsersService } from 'users/users.service';
            import { User } from 'users/user.entity';
            
            @Controller("auth")
            export class AuthController {
                constructor(
                    private readonly authService: AuthService,
                    private readonly userService: UsersService
                ) {}
                @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.getUserByEmail(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!' });
                } 
                @Post('register')
                async registerUser(@Response() res: any, @Body() body: User) {
                  if (!(body && body.email && body.password && body.last_name && body.first_name)) {
                    return res.status(HttpStatus.FORBIDDEN).json({ message: 'Username and password are required!' });
                  }
            
                  let user = await this.userService.getUserByEmail(body.email);
            
                  if (user) {
                    return res.status(HttpStatus.FORBIDDEN).json({ message: 'Email exists' });
                  } else {
                    let userSave = await this.userService.create(body);
                   if(userSave){
                     body.password=undefined;
                   }
                    return res.status(HttpStatus.OK).json(userSave);
                  }
                }
            }
            

            【讨论】:

            • 欢迎来到 StackOverflow 并感谢 y9ou 的回答。请为提问者和未来的研究人员提供一个解释,以便人们可以从您提供的内容中学习,而不是在不理解的情况下复制解决方案。
            【解决方案6】:

            你确定你已经添加了所有需要的包吗?尝试阅读身份验证文档https://docs.nestjs.com/techniques/authentication,它很好地解释了如何处理 JWT。

            【讨论】:

            • 您好,这并不能真正回答问题。当您有足够的声誉时,您就可以对帖子发表评论以要求澄清。
            猜你喜欢
            • 2019-06-29
            • 2020-01-25
            • 2017-05-13
            • 2016-01-02
            • 2020-08-17
            • 2022-08-23
            • 2019-09-13
            • 2021-03-02
            • 2019-01-22
            相关资源
            最近更新 更多