NestJs JWT 身份验证返回 401
Posted
技术标签:
【中文标题】NestJs JWT 身份验证返回 401【英文标题】:NestJs JWT Authentication returns 401 【发布时间】:2019-09-13 04:37:02 【问题描述】:我已经在 nestJs 中实现了 jwt 身份验证。但是,每当我尝试使用以下授权标头进行身份验证时:
Bearer <token> or JWT <token>
我得到了 401。这些是我的身份验证文件
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt')
constructor(private readonly authService: AuthService)
super(
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: `$process.env.SECRET`,
);
async validate(payload: Credentials)
const user: Account = await this.authService.validateAccount(payload);
if (!user)
throw new UnauthorizedException();
return user;
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt')
canActivate(context: ExecutionContext)
return super.canActivate(context);
handleRequest(err, user, info)
if (err || !user)
throw err || new UnauthorizedException();
return user;
这是我的身份验证模块
@Module(
imports: [
PassportModule.register( defaultStrategy: 'jwt' ),
JwtModule.register(
secretOrPrivateKey: `$process.env.SECRET`,
),
AccountModule,
],
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
exports: [PassportModule, AuthService],
)
export class AuthModule
【问题讨论】:
您能在authService.validateAccount
中添加console.log
吗?它被称为?它是否返回一个真实的值?
令我惊讶的是它没有被调用。
@Arsene 这对你有用吗,我遇到了同样的问题,registerAsync 由于某种原因不起作用。但是 register 方法有效
【参考方案1】:
validate
只会在您传递有效的 jwt 令牌时被调用。当令牌使用不同的秘密签名或过期时,validate
将永远不会被调用。确保您拥有有效的令牌。例如,您可以使用jwt debugger 检查您的令牌。
【讨论】:
令牌有效。但是我仍然收到 401。我怎么知道 Nestjs 管道中的问题在哪里? 您已经扩展了AuthGuard
,因此您可以将console.log
语句添加到它的方法中。您还可以在库代码中设置断点并进行调试。
由于您似乎使用的几乎都是标准设置,我不这么认为,不。正如您所说,您的令牌没有过期并且使用正确的秘密签名,它仍然可能是错误的标头格式,版本冲突,......
您好 NestJs 极客,请帮我解决这个问题。我已经和这个斗争了一段时间了。没有解决方案。
您必须提供更多信息,例如日志等或在codesandbox.io上创建可重现的版本【参考方案2】:
我遇到了类似的问题,nestjs 护照 jwt 模块在我的本地机器上运行良好,但在实时服务器上无法运行。经过半天的研究,我发现我的令牌头没有到达实时服务器,原因是我在实时服务器上使用了 nginx(proxy_pass)并且我的头字段名称是“access_token”所以出于某种原因 nginx 删除了它.
制作一个简单的全局中间件并检查您是否在标头中接收到令牌。
希望对某人有所帮助。
【讨论】:
【参考方案3】:我遇到了同样的问题。这是我的代码(工作)供您比较:
src/auth/auth.module.ts
import Module from '@nestjs/common';
import JwtModule from '@nestjs/jwt';
import AuthService from './auth.service';
import JwtStrategy from './jwt.strategy';
import UserModule from 'src/user/user.module';
import PassportModule from '@nestjs/passport';
@Module(
imports: [
PassportModule.register( defaultStrategy: 'jwt' ),
JwtModule.register(
secretOrPrivateKey: 'secretKey',
signOptions:
expiresIn: '1d',
,
),
UserModule,
],
providers: [AuthService, JwtStrategy],
exports: [PassportModule, AuthService],
)
export class AuthModule
src/auth/auth.service.ts
import Injectable from '@nestjs/common';
import JwtService from '@nestjs/jwt';
import JwtPayload from './interfaces/jwt-payload.interface';
import UserService from 'src/user/user.service';
@Injectable()
export class AuthService
constructor(
private readonly jwtService: JwtService,
private readonly userService: UserService,
)
makeToken(payload: JwtPayload)
const email = payload;
return this.jwtService.sign( email );
checkToken(token: string)
return this.jwtService.verify(token);
async validateUser(payload: JwtPayload)
return await this.userService.read(payload.email);
src/auth/jwt.strategy.ts
import Strategy, ExtractJwt, VerifiedCallback from 'passport-jwt';
import AuthService from './auth.service';
import PassportStrategy from '@nestjs/passport';
import Injectable, UnauthorizedException from '@nestjs/common';
import JwtPayload from './interfaces/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, done: VerifiedCallback)
const user = await this.authService.validateUser(payload);
if (!user)
done(new UnauthorizedException(), false);
return done(null, user);
src/auth/interfaces/jwt-payload.interface.ts
export interface JwtPayload
email: string;
src/account/account.module.ts
import Module from '@nestjs/common';
import AccountController from './account.controller';
import PassportModule from '@nestjs/passport';
import AuthModule from 'src/auth/auth.module';
@Module(
imports: [AuthModule],
controllers: [AccountController],
)
export class AccountModule
src/account/account.controller.ts
import Controller, UseGuards, Post from '@nestjs/common';
import AuthGuard from '@nestjs/passport';
@Controller('account')
export class AccountController
@Post('skills')
@UseGuards(AuthGuard())
updateSkills()
return console.log('something');
P.S.:我没有做 JwtAuthGuard。
希望对你有所帮助:)
【讨论】:
我不确定发生了什么,但它不起作用。【参考方案4】:您可以查看带有护照和 NestJS 的最小工作示例
https://github.com/leosuncin/nest-auth-example
与您的代码的主要区别:
@Module(
imports: [
PassportModule.register( defaultStrategy: 'jwt' ), // I don't do this because I explicity call every stratategy
JwtModule.register(
secretOrPrivateKey: 'secretKey',
signOptions:
expiresIn: '1d',
,
),
UserModule,
],
providers: [AuthService, JwtStrategy],
exports: [PassportModule, AuthService], // I don't do this
)
我不使用任何JwtAuthGuard
,只使用默认的。
【讨论】:
【参考方案5】:我遇到了这个问题,我解决了。
只需删除 $procces.env.JWT_SECRET
并执行其他操作,例如异步注册,我不知道为什么,但它可以工作。
【讨论】:
以上是关于NestJs JWT 身份验证返回 401的主要内容,如果未能解决你的问题,请参考以下文章
JWT 身份验证始终返回 401 HTTP 错误 asp.net core
Nest.js Auth Guard JWT 身份验证不断返回 401 未授权