You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用户认证返回JWT Token但未存储至数据库问题排查求助

JWT Token Not Saving to tokens Table in AdonisJS

Hey there! Let's break down why your JWT token isn't showing up in the tokens table, and walk through practical fixes tailored to different use cases.

Why This Happens

The core reason: AdonisJS's default JWT authentication is stateless. When you call auth.attempt() with the default jwt guard, it generates a self-contained JWT token that doesn't require database storage. The server validates the token using your app's secret key directly—no database lookup is needed for basic validation. That's exactly why your tokens table stays empty after successful auth.

If you need tokens to persist in the database (for example, to support token revocation later), you have two solid options:


Option 1: Switch to the Database Guard (Auto-Saves Tokens)

This is the simplest way to get tokens stored in the tokens table, as AdonisJS handles all storage logic automatically.

  1. Update your authentication configuration
    Open config/auth.js and set the default guard to database, then configure the guard details:

    module.exports = {
      guard: 'database', // Swap from 'jwt' to 'database'
      guards: {
        database: {
          driver: 'database',
          provider: {
            driver: 'lucid',
            model: 'App/Models/User',
          },
          table: 'tokens', // Link to your existing tokens table
          expiry: '30d' // Set your preferred token lifespan
        },
        // Keep the jwt guard if you need it for other use cases
        jwt: {
          driver: 'jwt',
          provider: {
            driver: 'lucid',
            model: 'App/Models/User',
          },
          secret: Env.get('APP_KEY'),
        }
      }
    }
    
  2. Adjust your autenticar method
    With the database guard, auth.attempt() automatically saves the token to the tokens table. Update your method to use proper error handling and extract the token value:

    async autenticar({ request, auth }) {
      const { email, password } = request.all();
      const retorno = {};
      try {
        // Database guard handles token storage behind the scenes
        const token = await auth.attempt(email, password);
        const user = await User.findBy('email', email);
        
        retorno.token = token.token;
        retorno.user = user.username;
        retorno.id = user.id;
      } catch (error) {
        retorno.data = "E-mail ou senha Incorretos";
      }
      return retorno;
    }
    

    This setup is ideal if you need to revoke tokens later (e.g., when a user logs out), since you can mark tokens as revoked directly in the database.


Option 2: Manually Store JWT Tokens (Keep JWT Guard)

If you want to retain the stateless benefits of JWT but still log tokens to the database, you'll need to manually create records in the tokens table.

  1. Create a Token Model
    First, ensure you have a Token model linked to your tokens table:

    // app/Models/Token.js
    'use strict'
    
    const Model = use('Model')
    
    class Token extends Model {
      user() {
        return this.belongsTo('App/Models/User')
      }
    }
    
    module.exports = Token
    
  2. Modify your auth method to save tokens
    Update your autenticar method to save the generated JWT to the database after calling auth.attempt():

    async autenticar({ request, auth }) {
      const { email, password } = request.all();
      const retorno = {};
      try {
        const token = await auth.attempt(email, password);
        const user = await User.findBy('email', email);
        
        // Manually create a token record in the database
        await user.tokens().create({
          token: token.token,
          type: 'jwt', // Label the token type for clarity
          is_revoked: false, // Mark as active
          expiry: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000) // 30-day expiry
        })
    
        retorno.token = token.token;
        retorno.user = user.username;
        retorno.id = user.id;
      } catch (error) {
        retorno.data = "E-mail ou senha Incorretos";
      }
      return retorno;
    }
    

    Note: With this approach, you'll need to add custom logic to check if a token is revoked (since JWT itself doesn't track database state). Use this if you just need to log tokens for auditing, not for active revocation.


Final Notes

Pick Option 1 if you need full control over token lifecycle (revocation, expiry checks via database). Choose Option 2 if you want the efficiency of stateless JWT but need to keep a record of issued tokens.

内容的提问来源于stack exchange,提问作者di0n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 10:27:44