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

Vue前端+Express后端:JWT安全存Cookie及获取User对象咨询

Hey Sam, I’ve been in exactly this situation before—setting up JWT with Vue and Express using secure cookies isn’t as straightforward as some tutorials make it seem, but once you get the hang of the security flags and flow, it’s solid. Let’s walk through every step you need:

First, you’ll need two packages: jsonwebtoken for creating/verifying tokens, and cookie-parser to handle cookies in Express. Install them with:

npm install jsonwebtoken cookie-parser

Configure Express & Login Endpoint

Set up your Express app to parse cookies, then in your login route, generate the JWT and attach it to a secure, HttpOnly cookie (this is the critical part for security):

const express = require('express');
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const app = express();

// Enable cookie parsing middleware
app.use(cookieParser());
app.use(express.json()); // To parse request bodies

// Login endpoint (validate credentials first in real code!)
app.post('/api/login', (req, res) => {
  // Assume you've checked username/password and fetched the user from DB
  const user = { id: 1, username: 'samzhang', email: 'sam@example.com' };

  // Sign the JWT with your secret key (store this in environment variables!)
  const token = jwt.sign(user, process.env.JWT_SECRET, { expiresIn: '1d' });

  // Set the cookie with strict security settings
  res.cookie('authToken', token, {
    httpOnly: true, // Blocks client-side JS from accessing the cookie (stops XSS)
    secure: process.env.NODE_ENV === 'production', // Only send over HTTPS in prod
    sameSite: 'strict', // Prevents CSRF attacks by restricting cross-site requests
    maxAge: 24 * 60 * 60 * 1000 // Cookie expires in 1 day (adjust as needed)
  });

  res.status(200).json({ message: 'Login successful!' });
});

Middleware to Verify Tokens & Attach User Object

Create a middleware that checks the cookie for the JWT, verifies it, and attaches the user object to the request. This protects your routes and lets you access the user data easily:

const authenticateToken = (req, res, next) => {
  // Pull the token from the cookie
  const token = req.cookies.authToken;

  if (!token) {
    return res.status(401).json({ message: 'Unauthorized: No token provided' });
  }

  // Verify the token
  jwt.verify(token, process.env.JWT_SECRET, (err, decodedUser) => {
    if (err) {
      return res.status(403).json({ message: 'Unauthorized: Invalid token' });
    }
    // Attach the user object to the request for use in routes
    req.user = decodedUser;
    next();
  });
};

// Example protected route to fetch the user object
app.get('/api/current-user', authenticateToken, (req, res) => {
  // Send the decoded user back to the frontend
  res.json(req.user);
});
2. Frontend (Vue): Retrieve the User Object

Since the cookie is HttpOnly, you can’t access it directly with Vue/JS (that’s intentional for security!). Instead, you’ll call your protected /api/current-user endpoint to get the user data, then store it in your app state (like Pinia or Vuex) for easy access.

Basic Vue Component Example

Here’s how to handle login and fetch the user in a Vue component using Axios:

<template>
  <div class="auth-container">
    <div v-if="user">
      <h2>Welcome, {{ user.username }}!</h2>
      <p>Your email: {{ user.email }}</p>
    </div>
    <form v-else @submit.prevent="handleLogin">
      <input v-model="username" type="text" placeholder="Username" />
      <input v-model="password" type="password" placeholder="Password" />
      <button type="submit">Login</button>
    </form>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';

const user = ref(null);
const username = ref('');
const password = ref('');

// Fetch user on component mount (for page reloads)
const fetchCurrentUser = async () => {
  try {
    const response = await axios.get('/api/current-user');
    user.value = response.data;
  } catch (err) {
    // User isn't logged in—handle this (e.g., redirect to login)
    console.log('User not authenticated');
  }
};

// Handle login request
const handleLogin = async () => {
  try {
    await axios.post('/api/login', {
      username: username.value,
      password: password.value
    });
    // After login succeeds, fetch the user data
    await fetchCurrentUser();
  } catch (err) {
    console.error('Login failed:', err.response?.data?.message || 'Unknown error');
  }
};

// Fetch user when the component loads
onMounted(fetchCurrentUser);
</script>

If you’re using Pinia (Vue’s official state manager), you can centralize the user state so it’s accessible across your app:

// stores/auth.js
import { defineStore } from 'pinia';
import axios from 'axios';

export const useAuthStore = defineStore('auth', {
  state: () => ({
    user: null
  }),
  actions: {
    async fetchUser() {
      try {
        const response = await axios.get('/api/current-user');
        this.user = response.data;
      } catch (err) {
        this.user = null;
      }
    },
    async login(credentials) {
      await axios.post('/api/login', credentials);
      await this.fetchUser();
    }
  }
});

Then in your component, use the store:

<script setup>
import { useAuthStore } from '@/stores/auth';
import { onMounted } from 'vue';

const authStore = useAuthStore();

onMounted(() => {
  authStore.fetchUser();
});
</script>
3. Critical Security Reminders
  • Never store JWT in localStorage: LocalStorage is vulnerable to XSS attacks, while HttpOnly cookies are inaccessible to client-side JS.
  • Use environment variables for secrets: Your JWT secret should never be hard-coded—store it in a .env file and use dotenv in Express.
  • Set token expiry: Short-lived tokens (like 1 day) reduce risk if a token is ever compromised. You can add a refresh token flow later for longer sessions.
  • Enable CORS correctly: Make sure your Express CORS configuration allows credentials (set credentials: true) so the browser sends the cookie with cross-origin requests (if your frontend is on a different port/domain).

That should cover everything you need! The flow is: login → backend sets secure cookie → frontend fetches user via protected endpoint → store user in app state. Let me know if you run into any issues with specific parts.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 18:03:00