# Vue獲取Token如何實現Token登錄
## 前言
在現代Web應用開發中,基于Token的身份驗證已成為主流方案。相比傳統的Session-Cookie機制,Token驗證具有無狀態、跨域友好、適合分布式系統等優勢。本文將詳細介紹在Vue.js項目中如何實現Token登錄的全流程,包括前端Token的獲取、存儲、發送以及相關安全策略。
---
## 一、Token認證基礎原理
### 1.1 什么是Token認證
Token(令牌)是一串由服務器生成的加密字符串,通常采用JWT(JSON Web Token)格式,包含三部分:
- Header:算法和類型聲明
- Payload:用戶信息及過期時間
- Signature:簽名驗證
### 1.2 工作流程
1. 客戶端提交登錄憑證(用戶名/密碼)
2. 服務端驗證通過后生成Token返回
3. 客戶端存儲Token并在后續請求中攜帶
4. 服務端驗證Token有效性并響應數據
---
## 二、Vue項目中實現Token登錄
### 2.1 安裝必要依賴
```bash
npm install axios vue-router vuex
<template>
<div class="login-container">
<form @submit.prevent="handleLogin">
<input v-model="username" type="text" placeholder="用戶名">
<input v-model="password" type="password" placeholder="密碼">
<button type="submit">登錄</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
username: '',
password: ''
}
},
methods: {
async handleLogin() {
try {
const response = await axios.post('/api/login', {
username: this.username,
password: this.password
});
// 獲取返回的Token
const token = response.data.token;
// 存儲Token
localStorage.setItem('authToken', token);
// 跳轉到首頁
this.$router.push('/dashboard');
} catch (error) {
console.error('登錄失敗:', error);
}
}
}
}
</script>
// store/auth.js
const state = {
token: localStorage.getItem('authToken') || null
};
const mutations = {
SET_TOKEN(state, token) {
state.token = token;
localStorage.setItem('authToken', token);
},
CLEAR_TOKEN(state) {
state.token = null;
localStorage.removeItem('authToken');
}
};
const actions = {
login({ commit }, credentials) {
return axios.post('/api/login', credentials)
.then(response => {
commit('SET_TOKEN', response.data.token);
return response;
});
},
logout({ commit }) {
commit('CLEAR_TOKEN');
}
};
export default {
namespaced: true,
state,
mutations,
actions
};
存儲方式 | 優點 | 缺點 |
---|---|---|
localStorage | 持久化存儲,不受頁面刷新影響 | 易受XSS攻擊 |
sessionStorage | 頁面關閉自動清除 | 同樣有XSS風險 |
Cookie | 可設置HttpOnly防XSS | 有CSRF風險,存儲空間有限 |
Vuex | 響應式管理 | 刷新丟失,需配合持久化方案使用 |
HttpOnly Cookie(服務端設置)
Set-Cookie: token=xxxxx; HttpOnly; Secure; SameSite=Strict
短期有效Token:設置合理的過期時間(如2小時)
Refresh Token機制:
// 響應示例
{
"access_token": "xxxxx",
"expires_in": 7200,
"refresh_token": "yyyyy"
}
// utils/axios.js
import axios from 'axios';
const service = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL,
timeout: 5000
});
// 請求攔截器
service.interceptors.request.use(
config => {
const token = localStorage.getItem('authToken');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
error => {
return Promise.reject(error);
}
);
// 響應攔截器
service.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
// Token過期處理
store.dispatch('auth/logout');
router.push('/login');
}
return Promise.reject(error);
}
);
export default service;
// router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import store from '@/store';
Vue.use(Router);
const router = new Router({
routes: [
{ path: '/login', component: Login },
{
path: '/dashboard',
component: Dashboard,
meta: { requiresAuth: true }
}
]
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!store.state.auth.token) {
next({
path: '/login',
query: { redirect: to.fullPath }
});
} else {
next();
}
} else {
next();
}
});
export default router;
// axios響應攔截器增強
service.interceptors.response.use(
response => response,
async error => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const refreshToken = localStorage.getItem('refreshToken');
const { data } = await axios.post('/api/refresh', { refreshToken });
store.commit('auth/SET_TOKEN', data.access_token);
localStorage.setItem('refreshToken', data.refresh_token);
originalRequest.headers['Authorization'] = `Bearer ${data.access_token}`;
return service(originalRequest);
} catch (err) {
store.dispatch('auth/logout');
return Promise.reject(err);
}
}
return Promise.reject(error);
}
);
即使使用Token也需防范CSRF:
// 在axios默認headers中添加CSRF Token
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken;
監聽storage事件實現多標簽頁狀態同步:
window.addEventListener('storage', (event) => {
if (event.key === 'authToken') {
if (!event.newValue) {
store.commit('auth/CLEAR_TOKEN');
}
}
});
describe('Auth Token', () => {
it('should store token after login', async () => {
const mockToken = 'mock-token-123';
axios.post.mockResolvedValue({ data: { token: mockToken } });
await store.dispatch('auth/login', {
username: 'test',
password: '123456'
});
expect(localStorage.getItem('authToken')).toBe(mockToken);
});
});
{
"access_token": "xxxxx",
"expires_in": 3600,
"token_type": "Bearer",
"refresh_token": "yyyyy"
}
Token認證在Vue項目中的實現需要前后端協同配合,本文詳細介紹了從Token獲取到持久化管理的完整流程。實際項目中還需根據具體需求考慮: 1. 第三方登錄集成(OAuth) 2. 權限細分(RBAC) 3. 服務端渲染(SSR)適配 4. 生物識別認證增強
通過合理實施Token認證機制,可以構建出既安全又用戶體驗良好的現代Web應用。 “`
注:本文實際約4200字,包含代碼示例、表格等結構化內容。如需調整字數或補充特定細節,可進一步修改擴展。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。