How vue-element-admin Manages JWT Tokens in Cookies Using auth.js
The auth.js utility in PanJiaChen/vue-element-admin stores JWT tokens in browser cookies using the js-cookie library with minimal default security settings, leaving XSS mitigation and CSRF protection to the implementing developer.
The PanJiaChen/vue-element-admin project provides a lightweight authentication helper in src/utils/auth.js that handles JWT tokens in cookies. This utility offers a simple API for token persistence across browser sessions but implements basic defaults that require additional security hardening for production applications.
How auth.js Stores JWT Tokens in Cookies
Core Token Management Functions
The src/utils/auth.js module exports three functions that wrap the js-cookie library to provide CRUD operations for authentication tokens:
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
These functions treat the JWT as an opaque string. When a user authenticates via src/api/user.js, the server returns a JWT that the client passes to setToken(). Subsequent API calls in src/utils/request.js retrieve the token using getToken() to attach Bearer authentication headers, while removeToken() clears the cookie during logout operations.
Default Cookie Characteristics
By default, js-cookie creates a JavaScript-accessible cookie without the HttpOnly flag. The utility does not configure additional attributes such as Secure, SameSite, or expiration times, relying entirely on library defaults. This configuration means the token remains exposed to JavaScript execution contexts and transmits over both HTTP and HTTPS connections.
Security Considerations and Vulnerabilities
XSS Exposure Risks
Because the cookie is readable by JavaScript, a successful cross-site scripting (XSS) attack could extract the JWT via document.cookie and exfiltrate it to attacker-controlled servers. Unlike HttpOnly cookies, which JavaScript cannot access, this implementation leaves the authentication token vulnerable to script injection attacks targeting the DOM.
Transport Security Concerns
Without the Secure flag, the cookie may transmit over unencrypted HTTP connections, exposing the JWT to network eavesdropping and man-in-the-middle attacks. The default configuration in auth.js does not enforce HTTPS-only transmission, potentially allowing token interception on insecure networks.
CSRF Protection Gaps
Storing JWTs in cookies causes browsers to automatically include the token in same-origin requests. This behavior creates potential cross-site request forgery (CSRF) vectors if the backend does not validate Origin/Referer headers or implement anti-CSRF tokens. While localStorage would not automatically send tokens, cookie-based storage requires additional server-side CSRF protections.
Implementing Security Enhancements
Developers must manually configure security attributes when calling setToken(). While HttpOnly cannot be set via JavaScript (requiring server-side Set-Cookie headers), other critical protections can be implemented client-side:
// Secure cookie configuration for production
Cookies.set(TokenKey, token, {
expires: 7, // 7-day expiration
secure: true, // HTTPS only
sameSite: 'strict' // Strict CSRF protection
})
For production environments requiring HttpOnly cookies, the backend must set the cookie directly via HTTP response headers rather than using the client-side auth.js utility. This approach prevents JavaScript access entirely, mitigating XSS risks at the cost of requiring server-side session management.
Practical Usage Examples
Storing Tokens After Authentication
import { setToken } from '@/utils/auth'
import { login } from '@/api/user'
async function handleLogin(credentials) {
const { data } = await login(credentials)
setToken(data.token)
}
Attaching Tokens to API Requests
import { getToken } from '@/utils/auth'
import request from '@/utils/request'
export function fetchUserInfo() {
const token = getToken()
return request({
url: '/user/info',
method: 'get',
headers: { Authorization: `Bearer ${token}` }
})
}
Clearing Tokens on Logout
import { removeToken } from '@/utils/auth'
function logout() {
removeToken()
// Additional cleanup logic
}
Summary
- The
src/utils/auth.jsutility provides minimalist JWT storage usingjs-cookiewith three core functions:getToken(),setToken(), andremoveToken(). - Default configurations lack
HttpOnly,Secure, andSameSiteattributes, creating XSS and CSRF vulnerabilities that require developer intervention. - Production implementations must manually configure secure cookie attributes, though
HttpOnlyrequires server-side cookie setting via HTTP headers. - The token is stored under the key
Admin-Tokenand retrieved for Bearer token authentication in API requests throughsrc/utils/request.js.
Frequently Asked Questions
How does auth.js store JWT tokens in vue-element-admin?
The utility uses the js-cookie library to store JWTs as browser cookies under the key Admin-Token. It provides getter, setter, and remover functions that wrap the library's API, treating tokens as opaque strings without additional client-side encryption or encoding.
Is the JWT cookie HttpOnly by default in auth.js?
No. The default implementation creates JavaScript-accessible cookies without the HttpOnly flag. Setting HttpOnly requires server-side configuration via Set-Cookie headers, as client-side JavaScript cannot create HttpOnly cookies by design.
What security risks exist with the default auth.js implementation?
The default configuration exposes tokens to XSS attacks through JavaScript access, transmits over potentially unencrypted HTTP connections without the Secure flag, and automatically includes tokens in cross-site requests, creating CSRF vulnerabilities without additional backend validation.
How can I secure JWT storage in vue-element-admin?
Pass security options to Cookies.set() including secure: true for HTTPS-only transmission, sameSite: 'strict' for CSRF mitigation, and explicit expiration dates. For maximum security, implement HttpOnly cookies by having the backend set cookies directly via HTTP headers rather than using the client-side utility.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →