jwt获取token_Koa开发之koa-jwt工作过程
最近的工作是開發(fā)一個分布式的服務(wù)系統(tǒng),選用的環(huán)境是node開發(fā)環(huán)境,由于需要全面的進行異步開發(fā)所以使用Koa框架,開發(fā)Web服務(wù)需要對用戶進行身份認證,所以就使用koa-jwt,為什么使用token這種方式網(wǎng)上有很多介紹token和session的區(qū)別我這里就不再贅述了。在給大家演示代碼之前我在這一章主要是介紹koa-jwt的工作流程在后面的一章中我將使用程序?qū)Υ蠹疫M行演示。
首先我在這附上koa-jwt的源代碼,然后為大家剖析其的工作流程。
源程序
koa-jwt的源程序的主程序在lib/index.js中
'use strict';const pAny = require('p-any');const unless = require('koa-unless');const verify = require('./verify');const getSecret = require('./get-secret');const resolveAuthHeader = require('./resolvers/auth-header');const resolveCookies = require('./resolvers/cookie');module.exports = (opts = {}) => { const { debug, getToken, isRevoked, key = 'user', passthrough, tokenKey } = opts; const tokenResolvers = [resolveCookies, resolveAuthHeader]; if (getToken && typeof getToken === 'function') { tokenResolvers.unshift(getToken); } const middleware = async function jwt(ctx, next) { let token; tokenResolvers.find(resolver => token = resolver(ctx, opts)); if (!token && !passthrough) { ctx.throw(401, debug ? 'Token not found' : 'Authentication Error'); } let { state: { secret = opts.secret } } = ctx; try { if (typeof secret === 'function') { secret = await getSecret(secret, token); } if (!secret) { throw new Error('Secret not provided'); } let secrets = Array.isArray(secret) ? secret : [secret]; const decodedTokens = secrets.map(async s => await verify(token, s, opts)); const decodedToken = await pAny(decodedTokens) .catch(function (err) { if (err instanceof pAny.AggregateError) { for (const e of err) { throw e; } } else { throw err; } }); if (isRevoked) { const tokenRevoked = await isRevoked(ctx, decodedToken, token); if (tokenRevoked) { throw new Error('Token revoked'); } } ctx.state[key] = decodedToken; if (tokenKey) { ctx.state[tokenKey] = token; } } catch (e) { if (!passthrough) { const msg = debug ? e.message : 'Authentication Error'; ctx.throw(401, msg, { originalError: e }); }else{ ctx.state.jwtOriginalError = e; } } return next(); }; middleware.unless = unless; return middleware;};2可配置參數(shù)
koa-jwt的可配置參數(shù)有debug,getToken,isRevoked,key,passthrough,tokenKey,secret,cookie
2.1debug參數(shù)
debug參數(shù)數(shù)據(jù)類型應(yīng)該是Boolean類型,用于表示是否處于調(diào)試狀態(tài),如果不是處于調(diào)試狀態(tài)返回的錯誤參數(shù)為Authentication Error如果處于調(diào)試狀態(tài)將會返回具體的錯誤原因。
2.2getToken參數(shù)
getToken參數(shù)數(shù)據(jù)類型應(yīng)該是函數(shù)類型,為用戶自定義的獲取請求token的函數(shù),如果沒有定義此參數(shù)將會從請求頭的authorization字段或者是cookie中的指定字段獲取token。
2.3isRevoked參數(shù)
isRevoked參數(shù)的數(shù)據(jù)類型為函數(shù)類型,為用戶自定義的token是否失效的函數(shù),如果沒有定義此參數(shù)將不進行token失效處理。
2.4key參數(shù)
key參數(shù)的數(shù)據(jù)類型應(yīng)該是string類型,將屬性名為key的屬性設(shè)置到ctx.state對象中,同時其屬性值為解密的token的值,默認值為user。
2.5passthrough參數(shù)
passthrough參數(shù)的數(shù)據(jù)類型應(yīng)該是Boolean類型,此參數(shù)用于對身份認證出現(xiàn)錯誤的時候是否直接拋出錯誤,如果此參數(shù)的值為真在身份認證過程中將不會直接拋出錯誤而是繼續(xù)執(zhí)行后面的程序,如果此參數(shù)值為假江湖在出現(xiàn)錯誤的地方將錯誤拋出。
2.6tokenKey參數(shù)
tokenKey參數(shù)的數(shù)據(jù)類型應(yīng)該為string類型,其作用與key的作用類型,將屬性名為tokenKey的屬性設(shè)置到ctx.state對象中,同時其屬性值為獲取token的方法。默認此參數(shù)為undefined。
2.7secret參數(shù)
secret參數(shù)的數(shù)據(jù)類型為函數(shù)類型返回值為字符串類型,或者直接是字符串類型,如果沒有定義此參數(shù)將會報錯所以此屬性為必要參數(shù)。此參數(shù)的作用是解密的秘鑰。
2.8cookie參數(shù)
cookie參數(shù)的數(shù)據(jù)類型應(yīng)該是字符串類型,用于指定從cookie中獲取token的指定的屬性名稱。
3Koa-jwt的工作流程
Koa-jwt的工作流程如下圖所示
從源程序和流程圖我們可以看到koa-jwt的處理過程為:
(1)獲取用戶的配置參數(shù)。
(2)設(shè)置獲取默認token的函數(shù),如果用戶定義了getToken方法將此方法放在獲取token方法數(shù)組的第一位。
(3)調(diào)用獲取token方法數(shù)組中的方法直到獲取到token或者是遍歷完數(shù)組。
(4)判斷是否獲取到token,如果獲取到執(zhí)行后面的過程,如果沒有獲取到拋出錯誤。
(5)判斷secret的類型是否是函數(shù)如果是函數(shù),調(diào)用此函數(shù)存入的值為頭部數(shù)據(jù)和載荷數(shù)據(jù)返回字符串型的秘鑰。
(6)判斷秘鑰是否為真,對于為真的執(zhí)行后面的參數(shù),對于不為真的拋出錯誤。
(7)根據(jù)秘鑰判斷token是否正確,對于token正確的執(zhí)行后面的過程,對于token不正確的拋出錯誤。
(8)根據(jù)是否定義失效處理函數(shù),如果定義失效處理函數(shù),對此token進行失效判斷,如果失效拋出錯誤,對于未失效繼續(xù)處理后面的內(nèi)容。
(9)根據(jù)定義key參數(shù)設(shè)置ctx.state的key屬性的值為獲取的解密的token
(10)根據(jù)用戶是否定義tokenKey設(shè)置ctx.state的tokenKey屬性的值為獲取token的函數(shù)。
(11)執(zhí)行后面的組件
總結(jié)
以上是生活随笔為你收集整理的jwt获取token_Koa开发之koa-jwt工作过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 橱窗广告宣传口号文案29句
- 下一篇: c语言大作业_2018 C语言大作业--