#@nestjs/passport compatibility
47 messages · Page 1 of 1 (latest)
Fastify kind of works with passport for things like passport-local and passport-jwt, but anything using passport-oauth needs some extra glue in your main.ts
const fastifyInstance: FastifyInstance = app.getHttpAdapter().getInstance()
fastifyInstance
.addHook('onRequest', async (req, res) => {
req.socket['encrypted'] = process.env.NODE_ENV === 'production'
})
.decorateReply('setHeader', function (name: string, value: unknown) {
this.header(name, value)
})
.decorateReply('end', function () {
this.send('')
})
I use fastify with passport-local and I still get 401 Unauthorized but I return true and the return true is executed
Have u idea why ?
Just a straight 401 usually menas an eror inside of the passport request. If it's with passport-local, I can only assume you didn't send a body with both username and password
I'd need to see the stragey and request for more infor, or you can use this snippet to log more of what's going on in a class that extends AuthGuard('local')
handleRequest(...args: Parameters<InstanceType<ReturnType<typeof AuthGuard>>['handleRequest']>) {
console.log(args);
return super.handleRequest(...args);
}
Oh that's it
I don't send username and password
That's what passport-local expects you to do
I paste this code where ?
There's a method to do without ?
It should be made as part ofthe main. It decorates the fastify request and reply objects to have methods that passport calls
Where in the main ?
After thefactory, but before the app.listen()
like this ?
Oh, sorry, I thought you were talking about the first snippet I pasted. Need more coffee 😪 ☕
no problem bro
No, that method would go inside of a guard class that extends AuthGuard('local')
Right, no errors so it's all good.
It's just a helpful debug method for when you get that stray 401 that you can't easily debug
oh ok
Do you throw an exception somewhere elese?
Got a minimum reproduction you can provide so that we can see what's happening?
yes
my guard file:
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-custom';
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import Redis from 'ioredis';
import { ethers } from 'ethers';
import { SiweService } from '@server/siwe/siwe.service';
@Injectable()
export class SiweAuthStrategy extends PassportStrategy(Strategy, 'siwe-auth') {
constructor(
private siweService: SiweService,
@InjectRedis() private readonly redis: Redis,
) {
super();
}
async validate(req: any) {
const { message, signature, nonce } = req.body;
console.log(req.body);
if (!message || !signature || !nonce) throw new UnauthorizedException();
const cached = await this.redis.get(nonce);
if (cached) throw new UnauthorizedException();
const parsedMessage = await this.siweService.verifyMessage(
message,
signature,
nonce,
);
if (
ethers.getAddress(parsedMessage.address) !==
ethers.getAddress(req.body.eoaAddress)
)
throw new UnauthorizedException();
await this.redis.set(nonce, parsedMessage.address);
return {test: true};
}
}
my strategy file:
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class SiweAuthGuard extends AuthGuard('siwe-auth') {}
my controller file:
@Post('/signup')
@UseGuards(SiweAuthGuard)
async signup(@Request() req: any, @Res() res: FastifyReply) {
if (!req.body.username || !req.body.eoaAddress) {
return res.code(422).send('Missing required information');
}
try {
const newUserDto: UserDTO = {
username: req.body.username,
eoaAddress: ethers.getAddress(req.body.eoaAddress),
};
const newUser = await this.userService.insertOne(newUserDto);
const jwtToken = this.jwtService.sign(
{
eoaAddress: newUser[0].eoaAddress,
},
{
secret: process.env.JWT_SECRET_KEY,
expiresIn: '1d',
},
);
res.code(200).send({
access_token: jwtToken,
});
} catch (e: any) {
switch (e.message) {
case 'signature verification failed':
return res.code(401).send({
message: 'signature verification failed',
});
default:
return res.code(500).send({
message: 'internal server error',
});
}
}
}
So I guess you're getting into that catch with the signature verification failing
maybe
wait I print to see
Not this
It don't enter in my controller
I put a console.log at the start of my controller
and It print nothing
Do you have any other guards bound? On the class, or using APP_GUARD or app.useGlobalGuards()? If not, I'm going to need to see a git repo that I can clone and work with locally
No other guard
go I dm
to send the repo
Why not make something you can post publicly so others can help and see the example too?
I'm not going to respond to the DM. You can either keep working on the private repo on your own, or you can make something publicly available that has minimal code to reproduce the same problem you're facing
I'm happy to provide support, and give direction, but I've learned through the years that private repositories are usually a pain to have to work with to handle for bug tracking