本篇文章為大家展示了怎么在Node.js中利用Koa實(shí)現(xiàn)JWT用戶認(rèn)證,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
在嘉黎等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需網(wǎng)站建設(shè),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),全網(wǎng)整合營銷推廣,成都外貿(mào)網(wǎng)站建設(shè),嘉黎網(wǎng)站建設(shè)費(fèi)用合理。
一、前置知識
基于Token的身份驗(yàn)證
Koajs 中文文檔
Koa 框架教程
二、環(huán)境
Microsoft Visual Studio 2017集成開發(fā)環(huán)境
Node.js v8.9.4Javascript運(yùn)行環(huán)境
三、開始動手,一步步來完善
1、創(chuàng)建基礎(chǔ)的靜態(tài)資源服務(wù)器、基礎(chǔ)架構(gòu)
以下是基本的代碼,實(shí)現(xiàn)靜態(tài)服務(wù)器,以及一個當(dāng)token驗(yàn)證異常時(shí)候的處理。
下面我們將在這個基本代碼下逐步增加注冊、登錄、信息的功能。
const path = require('path'); // 用于處理目錄路徑 const Koa = require('koa'); // web開發(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過期、token錯誤 */ 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 注冊 */ // 待辦事項(xiàng)…… /* GET /api/login 登錄 */ // 待辦事項(xiàng)…… /* GET /api/info 信息 */ // 待辦事項(xiàng)…… /* 靜態(tài)資源處理 */ app.use(serve(path.join(__dirname, 'static'))); /* 監(jiān)聽服務(wù)器端口 */ app.listen(website.port, () => { console.log(`${website.join()} 服務(wù)器已經(jīng)啟動!`); });
下面,我們將在注冊、登錄、信息的注釋底下添加實(shí)現(xiàn)的代碼。
2、路由權(quán)限控制
注冊、登錄接口、其它資源不需要認(rèn)證,信息接口需要認(rèn)證。
/* 路由權(quán)限控制 */ app.use(jwtKoa({ secret: secret }).unless({ // 設(shè)置login、register接口,可以不需要認(rèn)證訪問 path: [ /^\/api\/login/, /^\/api\/register/, /^((?!\/api).)*$/ // 設(shè)置除了私有接口外的其它資源,可以不需要認(rèn)證訪問 ] }));
3、注冊
/* POST /api/register 注冊 */ 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)注冊 // 待辦事項(xiàng)…… // 保存到新用戶到數(shù)據(jù)庫中 // 待辦事項(xiàng)…… // 是否注冊成功 let 是否注冊成功 = true; if (是否注冊成功) { // 返回一個注冊成功的JOSN數(shù)據(jù)給前端 return ctx.body = { ok: true, msg: '注冊成功', token: getToken({ user: body.user, password: body.password }) } } else { // 返回一個注冊失敗的JOSN數(shù)據(jù)給前端 return ctx.body = { ok: false, msg: '注冊失敗' } } })); /* 獲取一個期限為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)注冊 // 待辦事項(xiàng)…… // 判斷姓名、學(xué)號是否正確 // 待辦事項(xiàng)…… return ctx.body = { ok: true, msg: '登錄成功', token: getToken({ user: query.user, password: query.password }) } }));
前端獲取到token之后,可以保存在任意本地存儲里。
4、信息
/* GET /api/info 信息 */ app.use(route.get('/api/info', async (ctx, next) => { // 前端訪問時(shí)會附帶token在請求頭 payload = getJWTPayload(ctx.headers.authorization) /* * payload = { * user : "御焱", * iat : 1524042454, * exp : 1524056854 * } */ // 根據(jù) payload.user 查詢該用戶在數(shù)據(jù)庫中的信息 // 待辦事項(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: '獲取信息失敗' } } })); /* 通過token獲取JWT的payload部分 */ function getJWTPayload(token) { // 驗(yàn)證并解析JWT return jwt.verify(token.split(' ')[1], secret); }
上述內(nèi)容就是怎么在Node.js中利用Koa實(shí)現(xiàn)JWT用戶認(rèn)證,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。