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.