代碼地址以下:<br>http://www.demodashi.com/demo/13847.htmlhtml
運行環境
該項目基於 node(v7.8.0版本以上) 和 mongodb 數據庫,所以電腦上須要安裝這兩個軟件,安裝教程自行百度。mongodb教程。若是實在不懂安裝,請勿下載代碼。前端
運行項目
此處已表明已經安裝完成了node和mongodb,下載代碼以後,目錄結構是這樣子的: vue
接下來須要安裝依賴,執行 npm install
,完成以後,目錄結構下多了一個 node_modules 的目錄,這些就是依賴文件。node
接下來運行 mongodb服務,而後在項目根目錄下執行 node app.js
,運行node服務,而後在瀏覽器打開 http://localhost:3000 ,則能夠正常訪問了。 若是想修改頁面,能夠再執行 npm run serve
,運行 vue,訪問 http://localhost:8080 ,就能夠了ios
需求分析
在先後端分離的開發中,經過 Restful API 進行數據交互時,若是沒有對 API 進行保護,那麼別人就能夠很容易地獲取並調用這些 API 進行操做。那麼服務器端要如何進行鑑權呢?web
Json Web Token 簡稱爲 JWT,它定義了一種用於簡潔、自包含的用於通訊雙方之間以 JSON 對象的形式安全傳遞信息的方法。JWT 可使用 HMAC 算法或者是 RSA 的公鑰密鑰對進行簽名。算法
因此,咱們要給 API 加上 JWT 認證。mongodb
實現過程
首先用戶登陸時,輸入用戶名和密碼後請求服務器登陸接口,服務器驗證用戶名密碼正確後,生成token並返回給前端,前端存儲token,並在後面的請求中把token帶在請求頭中傳給服務器,服務器驗證token有效,返回正確數據。 數據庫
代碼實現
生成token
這裏註冊了個 /login
的路由,用於用戶登陸時獲取token。npm
const router = require('koa-router')(); const jwt = require('jsonwebtoken'); const userModel = require('../models/userModel.js'); router.post('/login', async (ctx) => { const data = ctx.request.body; if(!data.name || !data.password){ return ctx.body = { code: '000002', data: null, msg: '參數不合法' } } const result = await userModel.findOne({ name: data.name, password: data.password }) if(result !== null){ const token = jwt.sign({ name: result.name, _id: result._id }, 'my_token', { expiresIn: '2h' }); return ctx.body = { code: '000001', data: token, msg: '登陸成功' } }else{ return ctx.body = { code: '000002', data: null, msg: '用戶名或密碼錯誤' } } }); module.exports = router;
在驗證了用戶名密碼正確以後,調用 jsonwebtoken 的 sign() 方法來生成token,接收三個參數,第一個是載荷,用於編碼後存儲在 token 中的數據,也是驗證 token 後能夠拿到的數據;第二個是密鑰,本身定義的,驗證的時候也是要相同的密鑰才能解碼;第三個是options,能夠設置 token 的過時時間。
獲取token
接下來就是前端獲取 token,這裏是在 vue.js 中使用 axios 進行請求,請求成功以後拿到 token 保存到 localStorage 中。這裏登陸成功後,還把當前時間存了起來,除了判斷 token 是否存在以外,還能夠再簡單的判斷一下當前 token 是否過時,若是過時,則跳登陸頁面
submit(){ axios.post('/login', { name: this.username, password: this.password }).then(res => { if(res.code === '000001'){ localStorage.setItem('token', res.data); localStorage.setItem('token_exp', new Date().getTime()); this.$router.push('/'); }else{ alert(res.msg); } }) }
而後請求服務器端API的時候,把 token 帶在請求頭中傳給服務器進行驗證。每次請求都要獲取 localStorage 中的 token,這樣很麻煩,這裏使用了 axios 的請求攔截器,對每次請求都進行了取 token 放到 headers 中的操做。
axios.interceptors.request.use(config => { const token = localStorage.getItem('token'); config.headers.common['Authorization'] = 'Bearer ' + token; return config; })
驗證token
經過 koa-jwt 中間件來進行驗證,用法也很是簡單
const koa = require('koa'); const koajwt = require('koa-jwt'); const app = new koa(); // 錯誤處理 app.use((ctx, next) => { return next().catch((err) => { if(err.status === 401){ ctx.status = 401; ctx.body = 'Protected resource, use Authorization header to get access\n'; }else{ throw err; } }) }) app.use(koajwt({ secret: 'my_token' }).unless({ path: [/\/user\/login/] }));
經過 app.use 來調用該中間件,並傳入密鑰 {secret: 'my_token'}
,unless 能夠指定哪些 URL 不須要進行 token 驗證。token 驗證失敗的時候會拋出401錯誤,所以須要添加錯誤處理,並且要放在 app.use(koajwt()) 以前,不然不執行。
若是請求時沒有token或者token過時,則會返回401。
運行效果
登錄
獲取用戶信息
無效請求
Node.js 使用 JWT 進行用戶認證
代碼地址以下:<br>http://www.demodashi.com/demo/13847.html
注:本文著做權歸做者,由demo大師代發,拒絕轉載,轉載須要做者受權