什么是token?
token是一個用戶自定義的任意字符串,目前開發中,token都是在服務端生成並且token的值會保存到服務器后台。只有服務器和客戶端知道這個字符串,於是,這個token就成了兩者之間的秘鑰,它可以讓服務器確認請求是來自客戶端還是惡意的第三方。
為什么使用token?
基於token驗證的流程
- 客戶端使用用戶名跟密碼請求登錄
- 服務端收到請求,去驗證用戶名和密碼(后台根據請求去數據庫查找是否有該用戶)
- 驗證成功后,服務端會簽發一個token(該token值一般都會存入Redis數據庫中,並設置過期時間),再把這個token發送給客戶端
- 客戶端收到token之后,一般存儲在localStorage(HTML5新特性,只要不手動刪除存儲的內容,存儲的信息會一直存在)中
- 客戶端每次向服務端請求資源的時候需要帶着服務端簽發的token
- 服務端收到請求,然后去驗證客戶端請求里面帶着的token(token是否為該用戶的令牌以及token是否有效等),如果驗證成功,就向客戶端返回請求的數據
什么是axios?
Axios 是一個基於 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。
官方網址:www.axios.com/
中文文檔:www.kancloud.cn/yunye/axios…
vue實現axios攔截,token驗證
在簡單介紹完這些基礎知識以及用到的插件之后,我們便要開始今天的主題--token驗證。
首先在vue.js 中下載axios,npm install axios ,在 main.js 文件中全局使用:
import axios from 'axios'; Vue.prototype.$http = axios;
這樣引入之后,在其他的文件中便可以使用$http來調用接口:
getRoomDetail() { this.$http.get(this.roomDetailApi).then( res => { this.roomDetail = res.data.data; }, err => { console.log("接受數據錯誤" + err); } ).catch(err => { console.log("服務器錯誤" + err); }) }
以上步驟只是簡單的實現了前后台的交互(在前台調用后台接口來獲取數據),接下來我們便要進一步學習,實現token的驗證。
根據上面的介紹,我們在成功登錄后台並拿到返回給的token之后,需要使用localStorage全局存儲,實現代碼如下:
// 用戶登錄
login() { this.postData = { account: this.userInfo.account, password: this.$md5(this.userInfo.password), }; this.$http.post(configIp.apiConfig.user.login, this.postData) .then(res => { if (res.data.errno === 0) { this.$Message.success('登陸成功'); this.$router.push('roomInfo'); //全局存儲token
window.localStorage["token"] = JSON.stringify(res.data.data.token); } else { this.$Message.error('登錄失敗'); this.forgetPassword = true; } }).catch(err => { console.log("登錄失敗"); }) },
接下來,我們要做的就是設置請求頭,在之后的接口請求過程中,都要通過token的認證來獲取數據,添加 http.js 文件(攔截器)
import axios from 'axios'; import router from './router'; // axios 配置
axios.defaults.timeout = 8000; axios.defaults.baseURL = 'https://api.github.com'; // http request 攔截器
axios.interceptors.request.use( config => { if (localStorage.token) { //判斷token是否存在
config.headers.Authorization = localStorage.token; //將token設置成請求頭
} return config; }, err => { return Promise.reject(err); } ); // http response 攔截器
axios.interceptors.response.use( response => { if (response.data.errno === 999) { router.replace('/'); console.log("token過期"); } return response; }, error => { return Promise.reject(error); } ); export default axios;
添加攔截器之后,修改 main.js文件: 將上面
import axios from 'axios'; Vue.prototype.$http = axios;
改為:
import http from './http'; //此處問http文件的路徑
Vue.prototype.$http = http;
完成該步驟之后,基本的操作已經實現了,下面讓我們查看一下是否已經添加請求頭:

以上操作實現了添加請求頭token,在之后的請求中,會自動添加該請求頭,但是不是每一個頁面都需要登錄權限(后台會實現不需要進行token驗證的篩選),那么前台也需要通過路由的meta標簽對需要做校驗的路由頁面進行標記,其他頁面則不需要驗證,代碼如下:
{ path: '/userInfo', name: 'userInfo', meta: { requireAuth: true, // 該路由項需要權限校驗
} component: userInfo }, { path: '/userList', name: 'userList', // 該路由項不需要權限校驗
component: userInfo }
之后,我們可以定義一個路由防衛,每次路由跳轉,我們都來做一下權限校驗,參考代碼如下:
router.beforeEach((to, from, next) => { if (to.meta.requireAuth) { // 判斷該路由是否需要登錄權限
if (localStorage.token) { // 獲取當前的token是否存在
console.log("token存在"); next(); } else { console.log("token不存在"); next({ path: '/login', // 將跳轉的路由path作為參數,登錄成功后跳轉到該路由
query: {redirect: to.fullPath} }) } } else { // 如果不需要權限校驗,直接進入路由界面
next(); } });
到此,用vue.js實現前台添加請求頭,通過axios設置攔截器添加token就已經實現了。
直接添加token
如果不使用攔截器,直接使用axios請求的話,有時候需要在post請求頭部添加token,語法為:
let params = { //請求參數設置
} axios.post(url,params,{ headers:{ 'token':localStorage.getItem("token") } }).then(res=>{ console.log('res=>',res) })
如果是get請求添加token,語法為:
let args = { //請求參數設置
} axios.get(url,{ headers:{ 'token':localStorage.getItem("token") }, params:args }).then(res=>{ console.log('res=>',res) })
