Node.js的Koa實(shí)現(xiàn)JWT用戶認(rèn)證方法
本文介紹了Node.js的Koa實(shí)現(xiàn)JWT用戶認(rèn)證方法,分享給大家,具體如下:

一、前置知識(shí)
二、環(huán)境
- Microsoft Visual Studio 2017集成開(kāi)發(fā)環(huán)境
- Node.js v8.9.4Javascript運(yùn)行環(huán)境
三、開(kāi)始動(dòng)手,一步步來(lái)完善
1、創(chuàng)建基礎(chǔ)的靜態(tài)資源服務(wù)器、基礎(chǔ)架構(gòu)
以下是基本的代碼,實(shí)現(xiàn)靜態(tài)服務(wù)器,以及一個(gè)當(dāng)token驗(yàn)證異常時(shí)候的處理。
下面我們將在這個(gè)基本代碼下逐步增加注冊(cè)、登錄、信息的功能。
const path = require('path'); // 用于處理目錄路徑
const Koa = require('koa'); // web開(kāi)發(fā)框架
const serve = require('koa-static'); // 靜態(tài)資源處理
const route = require('koa-route'); // 路由中間件
const jwt = require('jsonwebtoken'); // 用于簽發(fā)、解析`token`
const jwtKoa = require('koa-jwt'); // 用于路由權(quán)限控制
const koaBody = require('koa-body'); // 用于查詢字符串解析到`ctx.request.query`
const app = new Koa();
const website = {
scheme: 'http',
host: 'localhost',
port: 1337,
join: function () {
return `${this.scheme}://${this.host}:${this.port}`
}
}
/* jwt密鑰 */
const secret = 'secret';
/* 當(dāng)token驗(yàn)證異常時(shí)候的處理,如token過(guò)期、token錯(cuò)誤 */
app.use((ctx, next) => {
return next().catch((err) => {
if (err.status === 401) {
ctx.status = 401;
ctx.body = {
ok: false,
msg: err.originalError ? err.originalError.message : err.message
}
} else {
throw err;
}
});
});
/* 查詢字符串解析到`ctx.request.query` */
app.use(koaBody());
/* 路由權(quán)限控制 */
// 待辦事項(xiàng)……
/* POST /api/register 注冊(cè) */
// 待辦事項(xiàng)……
/* GET /api/login 登錄 */
// 待辦事項(xiàng)……
/* GET /api/info 信息 */
// 待辦事項(xiàng)……
/* 靜態(tài)資源處理 */
app.use(serve(path.join(__dirname, 'static')));
/* 監(jiān)聽(tīng)服務(wù)器端口 */
app.listen(website.port, () => {
console.log(`${website.join()} 服務(wù)器已經(jīng)啟動(dòng)!`);
});
下面,我們將在注冊(cè)、登錄、信息的注釋底下添加實(shí)現(xiàn)的代碼。
2、路由權(quán)限控制
注冊(cè)、登錄接口、其它資源不需要認(rèn)證,信息接口需要認(rèn)證。
/* 路由權(quán)限控制 */
app.use(jwtKoa({ secret: secret }).unless({
// 設(shè)置login、register接口,可以不需要認(rèn)證訪問(wèn)
path: [
/^\/api\/login/,
/^\/api\/register/,
/^((?!\/api).)*$/ // 設(shè)置除了私有接口外的其它資源,可以不需要認(rèn)證訪問(wèn)
]
}));
3、注冊(cè)
/* POST /api/register 注冊(cè) */
app.use(route.post('/api/register', async (ctx, next) => {
const body = ctx.request.body;
/*
* body = {
* user : '御焱',
* password : '123456'
* }
*/
// 判斷 body.user 和 body.password 格式是否正確
// 待辦事項(xiàng)……
// 判斷用戶是否已經(jīng)注冊(cè)
// 待辦事項(xiàng)……
// 保存到新用戶到數(shù)據(jù)庫(kù)中
// 待辦事項(xiàng)……
// 是否注冊(cè)成功
let 是否注冊(cè)成功 = true;
if (是否注冊(cè)成功) {
// 返回一個(gè)注冊(cè)成功的JOSN數(shù)據(jù)給前端
return ctx.body = {
ok: true,
msg: '注冊(cè)成功',
token: getToken({ user: body.user, password: body.password })
}
} else {
// 返回一個(gè)注冊(cè)失敗的JOSN數(shù)據(jù)給前端
return ctx.body = {
ok: false,
msg: '注冊(cè)失敗'
}
}
}));
/* 獲取一個(gè)期限為4小時(shí)的token */
function getToken(payload = {}) {
return jwt.sign(payload, secret, { expiresIn: '4h' });
}

3、登錄
/* GET /api/login 登錄 */
app.use(route.get('/api/login', async (ctx, next) => {
const query = ctx.request.query;
/*
* query = {
* user : '御焱',
* password : '123456'
* }
*/
// 判斷 query.user 和 query.password 格式是否正確
// 待辦事項(xiàng)……
// 判斷是否已經(jīng)注冊(cè)
// 待辦事項(xiàng)……
// 判斷姓名、學(xué)號(hào)是否正確
// 待辦事項(xiàng)……
return ctx.body = {
ok: true,
msg: '登錄成功',
token: getToken({ user: query.user, password: query.password })
}
}));

前端獲取到token之后,可以保存在任意本地存儲(chǔ)里。
4、信息
/* GET /api/info 信息 */
app.use(route.get('/api/info', async (ctx, next) => {
// 前端訪問(wèn)時(shí)會(huì)附帶token在請(qǐng)求頭
payload = getJWTPayload(ctx.headers.authorization)
/*
* payload = {
* user : "御焱",
* iat : 1524042454,
* exp : 1524056854
* }
*/
// 根據(jù) payload.user 查詢?cè)撚脩粼跀?shù)據(jù)庫(kù)中的信息
// 待辦事項(xiàng)……
const info = {
name: '御焱',
age: 10,
sex: '男'
}
let 獲取信息成功 = true;
if (獲取信息成功) {
return ctx.body = {
ok: true,
msg: '獲取信息成功',
data: info
}
} else {
return ctx.body = {
ok: false,
msg: '獲取信息失敗'
}
}
}));
/* 通過(guò)token獲取JWT的payload部分 */
function getJWTPayload(token) {
// 驗(yàn)證并解析JWT
return jwt.verify(token.split(' ')[1], secret);
}

訪問(wèn)需要認(rèn)證的接口時(shí),需要在request頭附帶Authorization:Bearer [token]字段。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
原文鏈接地址:https://segmentfault.com/a/1190000014727547
相關(guān)文章
NodeJs下的測(cè)試框架Mocha的簡(jiǎn)單介紹
本篇文章主要介紹了NodeJs下的測(cè)試框架Mocha的簡(jiǎn)單介紹,是目前最為流行的javascript框架之一,在本文我們重點(diǎn)介紹它在NodeJs上的使用。有興趣的可以了解一下。2017-02-02
詳解Node中導(dǎo)入模塊require和import的區(qū)別
本篇文章主要介紹了詳解Node中導(dǎo)入模塊require和import的區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-08-08
在nodejs中創(chuàng)建child process的方法
這篇文章主要介紹了在nodejs中創(chuàng)建child process的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
node基于async/await對(duì)mysql進(jìn)行封裝
這篇文章主要介紹了node基于async/await對(duì)mysql進(jìn)行封裝,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06
Node.js實(shí)現(xiàn)登錄注冊(cè)功能
這篇文章主要為大家詳細(xì)介紹了Node.js實(shí)現(xiàn)登錄注冊(cè)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
nodejs配置express服務(wù)器運(yùn)行自動(dòng)打開(kāi)瀏覽器詳細(xì)步驟
在nodejs中使用express來(lái)搭建框架可以說(shuō)是非常的簡(jiǎn)單方便,下面這篇文章主要給大家介紹了關(guān)于nodejs配置express服務(wù)器運(yùn)行自動(dòng)打開(kāi)瀏覽器的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01

