DEV Community

DoriDoro
DoriDoro

Posted on

Using JWT with Django REST Framework and Vue.js

Here’s how JWT (JSON Web Token) works in Django DRF:

Step-by-Step JWT Flow

1️⃣ User Logs In

  • Frontend sends username & password to /api/token/.
  • Django returns access and refresh tokens.
{
  "access": "eyJhbGciOi... (valid for 60 minutes)",
  "refresh": "eyJhbGciOi... (valid for 7 days)"
}
Enter fullscreen mode Exit fullscreen mode

2️⃣ Frontend Stores the Tokens

  • The access token is stored in Vuex, Pinia, or LocalStorage.
  • The refresh token is stored in HTTP-only cookies (for security).

3️⃣ Frontend Sends Access Token with Every API Request

  • When making a request to Django, Vue.js adds the token to the Authorization header:
fetch("/api/chats/", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${accessToken}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(data)
});
Enter fullscreen mode Exit fullscreen mode

4️⃣ Backend Verifies the Token

  • DRF checks if the access token is valid.
  • If valid → The request is processed.
  • If expired → The backend rejects it (401 Unauthorized).

5️⃣ Frontend Uses Refresh Token to Get a New Access Token

  • If the access token expires, Vue.js sends the refresh token to /api/token/refresh/ to get a new one.

Request to Refresh Token:

{
  "refresh": "eyJhbGciOi... (old refresh token)"
}
Enter fullscreen mode Exit fullscreen mode

Backend Response (New Access Token):

{
  "access": "eyJhbGciOi... (new access token)"
}
Enter fullscreen mode Exit fullscreen mode

6️⃣ Frontend Stores the New Access Token and Continues

The new access token replaces the old one and API requests continue normally.

Image description


Vue.js Example: Sending JWT Token

When the frontend sends a request to create a chat, it includes the JWT token:

async function sendChat(question, personas) {
  const accessToken = localStorage.getItem("accessToken");

  const response = await fetch("/api/chats/", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${accessToken}`
    },
    body: JSON.stringify({
      question: question,
      personas: personas.map(p => p.name),
      responses: personas.map(p => ({
        persona: p.name,
        response_text: "Simulated AI response"
      }))
    })
  });

  if (response.status === 401) {
    console.log("Access token expired. Refreshing...");
    await refreshToken();
    return sendChat(question, personas);
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)