typescript - Pourquoi mon serveur basé sur NestJS utilisant Passport retourne-t-il toujours 401 pour mes points de terminaison, même lorsqu'un jeton JWT valide est présent ?
Tu n'vas pas le croire, mais je suis en train de créer une API pour un serveur Todo ! Youpi !
J'utilise Nestjs, Auth0 et Passport pour gérer mon authentification. J'ai vérifié que le client envoie un jeton valide.
Je m'arrache aussi les cheveux parce que je n'arrive pas à faire en sorte que le contrôleur /todo renvoie autre chose qu'une erreur 401.
J'ai fait ma diligence raisonnable sur Google, mais hélas, rien ne semble fonctionner.
Donc, voici ma stratégie JWT :
import { passportJwtSecret } from 'jwks-rsa';
import { ExtractJwt, Strategy, VerifiedCallback } from 'passport-jwt';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor() {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`,
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
//jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('jwt'),
audience: 'http://localhost:3000',
issuer: `https://${process.env.AUTH0_DOMAIN}/`,
});
}
validate(payload: any, done: VerifiedCallback) {
if (!payload) {
console.log('DENIED!!!!!');
done(new UnauthorizedException(), false); // 2
}
return done(null, payload);
}
}
Voici mon contrôleur de tâches :
import { ValidationPipe } from './../utils/validation.pipe';
import {
Controller,
Get,
Param,
Body,
Post,
Put,
Delete,
Query,
ParseBoolPipe,
UsePipes,
UseGuards,
} from '@nestjs/common';
import { ToDosService } from './to-dos.service';
import { classToPlain } from 'class-transformer';
import { Todo } from '../models/todo.model';
import { ObjectID } from 'typeorm';
import { AuthGuard } from '@nestjs/passport';
@Controller('todos')
@UseGuards(AuthGuard('jwt'))
export class ToDosController {
constructor(private todosService: ToDosService) {}
@Get()
async getAllTodos() {
const todosEntities = await this.todosService.getAllTodos();
const todos = classToPlain(todosEntities);
return todos;
}
@Get('complete')
async getTodos(@Query('iscomplete', new ParseBoolPipe()) isComplete) {
let todosEntities: Todo[];
if (isComplete) {
todosEntities = await this.todosService.getCompletedTodos();
} else {
todosEntities = await this.todosService.getIncompleteTodos();
}
const todos = classToPlain(todosEntities);
return todos;
}
@Get(':id')
async getTodo(@Param('id') id: ObjectID): Promise<Todo> {
return this.todosService.getTodo(id);
}
@UsePipes(new ValidationPipe())
@Post()
async createTodo(@Body() todo: Todo) {
return this.todosService.createTodo(todo);
}
@Put(':id')
async updTodo(@Param('id') id: ObjectID, @Body() todo: Todo) {
return this.todosService.updateTodo(id, todo);
}
@Delete(':id')
async deleteTodo(@Param('id') id: ObjectID) {
return this.todosService.deleteTodo(id);
}
}
Si vous le souhaitez, un aperçu complet du projet peut être trouvé ici :
https://github.com/NickHodges/nestjstodoserver
L'appel à http:/localhost:3000/todos renvoie 401 peu importe ce que j'essaie.
Des idées de quelqu'un ?