Node.js 使用JWT進行用戶認證


代碼地址如下:
http://www.demodashi.com/demo/13847.html

運行環境

該項目基於 node(v7.8.0版本以上) 和 mongodb 數據庫,因此電腦上需要安裝這兩個軟件,安裝教程自行百度。mongodb教程。如果實在不懂安裝,請勿下載代碼。

運行項目

此處已代表已經安裝完成了node和mongodb,下載代碼之后,目錄結構是這樣子的:

接下來需要安裝依賴,執行 npm install,完成之后,目錄結構下多了一個 node_modules 的目錄,這些就是依賴文件。

接下來運行 mongodb服務,然后在項目根目錄下執行 node app.js,運行node服務,然后在瀏覽器打開 http://localhost:3000 ,則可以正常訪問了。
如果想修改頁面,可以再執行 npm run serve,運行 vue,訪問 http://localhost:8080 ,就可以了

需求分析

在前后端分離的開發中,通過 Restful API 進行數據交互時,如果沒有對 API 進行保護,那么別人就可以很容易地獲取並調用這些 API 進行操作。那么服務器端要如何進行鑒權呢?

Json Web Token 簡稱為 JWT,它定義了一種用於簡潔、自包含的用於通信雙方之間以 JSON 對象的形式安全傳遞信息的方法。JWT 可以使用 HMAC 算法或者是 RSA 的公鑰密鑰對進行簽名。

所以,我們要給 API 加上 JWT 認證。

實現過程

首先用戶登錄時,輸入用戶名和密碼后請求服務器登錄接口,服務器驗證用戶名密碼正確后,生成token並返回給前端,前端存儲token,並在后面的請求中把token帶在請求頭中傳給服務器,服務器驗證token有效,返回正確數據。

代碼實現

生成token

這里注冊了個 /login 的路由,用於用戶登錄時獲取token。

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 進行用戶認證

代碼地址如下:
http://www.demodashi.com/demo/13847.html

注:本文著作權歸作者,由demo大師代發,拒絕轉載,轉載需要作者授權


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM