typescript - argon2 verifierar nästan alltid true när man jämför jwt-token
Jag använder nestjs på min server, jag använder logik baserad på passport för autentisering och jag har problem med min refresh-token. Jag använder den bara för att uppdatera mina access- och refresh-tokens i refreshTokens-metoden och jag hashar den med argon2. Jag hade problem med att hash:a token med bcrypt, eftersom token var för lång för att bcrypt skulle kunna hash:a den korrekt och den returnerade alltid true vid verifiering.
async refreshTokens(userId: number, rt: string, res: Response): Promise<AccessToken> {
const admin = await this.adminService.findAdminById(userId)
if (!admin || !admin.refreshToken) throw new ForbiddenException('Access denied')
console.log(rt, 'service method')
const rtMatches = await argon2.verify(admin.refreshToken, rt)
if (!rtMatches) throw new ForbiddenException('Access denied')
const tokens = await this.createTokens(admin.id, admin.userName)
await this.updateRefreshToken(admin.id, tokens.refresh_token)
res.cookie('refresh_token', `${tokens.refresh_token}`, {
httpOnly: true
})
return {
access_token: tokens.access_token
}
}
I koden ovan får min metod userId (utvinns från uppdateringstoken i dekoratören) för att hitta admin i databasen, sedan jämförs värdet av uppdateringstoken som sparats i databasen med rt (som utvinns från cookies och sedan skickas in i refreshTokens-metoden), för jämförelse används argon2.verify()-metoden.
Jag använder Postman för att anropa endpoints.
Så, när jag loggar in och får åtkomst- och uppfräschnings-token skickar jag uppfräschnings-token till cookies i Postman och anropar refreshTokens-metoden via Postman och metoden körs framgångsrikt och rtMatches returnerar true. Sedan kontrollerar jag min MySQL-databas och hash av uppfräschnings-token där har ändrats. Och problemet uppstår när jag anropar refreshTokens-metoden igen med den första token, som tidigare skrivits över av den nya token, och rtMatches-värdet borde vara false, men det är sant. Och jag kan anropa denna endpoint oändligt och rtMatches kommer alltid att förbli true.
För mer sammanhang:
async updateRefreshToken(userId: number, rt: string) {
const hash = await this.hashData(rt)
await this.adminService.updateRefreshToken(userId, hash)
}
async hashData(data: string) {
return await argon2.hash(data)
}
Om du behöver mer detaljerad information kommer jag gärna att ge den, och ursäkta om jag har några misstag i förklaringen. Jag är inte engelsktalande från början
P.S.
Jag glömde skriva varför det nästan alltid returnerar sant vid verifiering.
async updateRefreshToken(userId: number, rt: string) {
const hash = await this.hashData(rt)
const first = await argon2.verify(hash, rt) // always returns true
const second = await argon2.verify(hash, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEsInVzZXJOYW1lIjoiMTIzMTIzIiwiaWF0IjoxNzM3ODM5NzA1LCJleHAiOjE3Mzg0NDQ1MDV9.N8_5IA4GCDbxQg7Wda8JS78Qm0ojesgFyZqlW_00nR0') // always returns false
console.log(first, 1)
console.log(second, 2)
console.log('******************')
await this.adminService.updateRefreshToken(userId, hash)
}
när jag använde dessa loggar för att debugga såg jag en intressant bugg. I den modifierade updateRefreshToken-metoden ovan är rt lika med token i strängformat nedan, så de har samma värde men vid verifiering returnerar de olika resultat. Jag vet inte varför det fungerar så här.
Svar #1
Jag började utveckla frontend och försökte där logga in och sedan anropa refresh-endpoint från webbläsaren och det fungerade, så det måste ha varit något fel med Postman, tror jag. Nu fungerar allt som jag ville.