英文:
Cannot access route with auth guard in app controller, validate function in local strategy file wont execute NestJs
问题
我尝试在我的 Nestjs 和 Prisma 的 rest API 的 app.controller.ts 中访问登录路由,但最终收到了 401 错误作为响应。
我一直在遵循 Nestjs 官方文档 (https://docs.nestjs.com/security/authentication)。
./app.controller.ts :
```typescript
import { LocalAuthGuard } from './auth/local-auth.guards';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly authService: AuthService,
) {}
@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
return req.user;
}
./auth/local.strategy.ts:
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super();
}
async validate(username: string, password: string): Promise<any> {
const user = await this.authService.validateUser(username, password);
console.log('validation');
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
./auth/local-auth.guards.ts:
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
基本上,从我理解的来看,@UseGuards(LocalAuthGuard)
的使用将允许访问 /auth/login
函数,如果 validate(username: string, password: string)
不抛出异常,不幸的是,它从未执行,我一直收到来自某个地方的 401 错误,但我不知道原因(因此发布此帖)。
感谢阅读,非常感谢您的帮助。
<details>
<summary>英文:</summary>
I try to acces my login route in the app.controller.ts for my rest api with Nestjs and Prisma, but i end up with a 401 error as a response.
I have been following nestjs official documentation (https://docs.nestjs.com/security/authentication).
./app.controller.ts :
import { LocalAuthGuard } from './auth/local-auth.guards';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly authService: AuthService,
) {}
@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
return req.user;
}
./auth/local.strategy.ts:
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super();
}
async validate(username: string, password: string): Promise<any> {
const user = await this.authService.validateUser(username, password);
console.log('validation');
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
./auth/local-auth.guards.ts:
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
basically from what i understand, the use of `@UseGuards(LocalAuthGuard)` will allow access to the `/auth/login` function if the `validate(username: string, password: string)` doesnt throw, unfortunaly it never execute and i keep getting that 401 error coming from somewhere but i have no clue (hence this post).
Thank you for reading, and your help will be much appreciated.
</details>
# 答案1
**得分**: 1
Nine times out of ten, this is because you aren't sending a `POST` request with body parameters of `username` and `password`. If you want to use something like `email` instead you need to pass the object `{ usernameField: 'email' }` to `super()` in the `constructor()` of your `LocalStrategy`. If that's _not_ the case, then more details will be needed to be added to your question such as what your request looks like.
You can also try adding this snippet to your `LocalAuthGuard` to get a better idea of what is happening when that error comes through:
```typescript
handleRequest(...args: Parameters<InstanceType<ReturnType<typeof AuthGuard>>['handleRequest']> {
console.log(args);
return super.handleRequest(...args);
}
英文:
Nine times out of ten, this is because you aren't sending a POST
request with body parameters of username
and password
. If you want to use something like email
instead you need to pass the object { usernameField: 'email' }
to super()
in the constructor()
of your LocalStrategy
. If that's not the case, then more details will be needed to be added to your question such as what your request looks like.
You can also try adding this snippet to your LocalAuthGuard
to get a better idea of what is happening when that error comes through:
handleRequest(...args: Parameters<InstanceType<ReturnType<typeof AuthGuard>>['handleRequest']> {
console.log(args);
return super.handleRequest(...args);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论