jwt获取token_Koa开发之koa-jwt工作过程

最近的工作是开发一个分布式的服务系统,选用的环境是node开发环境,由于需要全面的进行异步开发所以使用Koa框架,开发Web服务需要对用户进行身份认证,所以就使用koa-jwt,为什么使用token这种方式网上有很多介绍token和session的区别我这里就不再赘述了。在给大家演示代码之前我在这一章主要是介绍koa-jwt的工作流程在后面的一章中我将使用程序对大家进行演示。

首先我在这附上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可配置参数

koa-jwt的可配置参数有debug,getToken,isRevoked,key,passthrough,tokenKey,secret,cookie

2.1debug参数

debug参数数据类型应该是Boolean类型,用于表示是否处于调试状态,如果不是处于调试状态返回的错误参数为Authentication Error如果处于调试状态将会返回具体的错误原因。

2.2getToken参数

getToken参数数据类型应该是函数类型,为用户自定义的获取请求token的函数,如果没有定义此参数将会从请求头的authorization字段或者是cookie中的指定字段获取token。

2.3isRevoked参数

isRevoked参数的数据类型为函数类型,为用户自定义的token是否失效的函数,如果没有定义此参数将不进行token失效处理。

2.4key参数

key参数的数据类型应该是string类型,将属性名为key的属性设置到ctx.state对象中,同时其属性值为解密的token的值,默认值为user。

2.5passthrough参数

passthrough参数的数据类型应该是Boolean类型,此参数用于对身份认证出现错误的时候是否直接抛出错误,如果此参数的值为真在身份认证过程中将不会直接抛出错误而是继续执行后面的程序,如果此参数值为假江湖在出现错误的地方将错误抛出。

2.6tokenKey参数

tokenKey参数的数据类型应该为string类型,其作用与key的作用类型,将属性名为tokenKey的属性设置到ctx.state对象中,同时其属性值为获取token的方法。默认此参数为undefined。

2.7secret参数

secret参数的数据类型为函数类型返回值为字符串类型,或者直接是字符串类型,如果没有定义此参数将会报错所以此属性为必要参数。此参数的作用是解密的秘钥。

2.8cookie参数

cookie参数的数据类型应该是字符串类型,用于指定从cookie中获取token的指定的属性名称。

3Koa-jwt的工作流程

Koa-jwt的工作流程如下图所示

581a3d7c68229546fb09a471278e65d8.png

从源程序和流程图我们可以看到koa-jwt的处理过程为:

(1)获取用户的配置参数。

(2)设置获取默认token的函数,如果用户定义了getToken方法将此方法放在获取token方法数组的第一位。

(3)调用获取token方法数组中的方法直到获取到token或者是遍历完数组。

(4)判断是否获取到token,如果获取到执行后面的过程,如果没有获取到抛出错误。

(5)判断secret的类型是否是函数如果是函数,调用此函数存入的值为头部数据和载荷数据返回字符串型的秘钥。

(6)判断秘钥是否为真,对于为真的执行后面的参数,对于不为真的抛出错误。

(7)根据秘钥判断token是否正确,对于token正确的执行后面的过程,对于token不正确的抛出错误。

(8)根据是否定义失效处理函数,如果定义失效处理函数,对此token进行失效判断,如果失效抛出错误,对于未失效继续处理后面的内容。

(9)根据定义key参数设置ctx.state的key属性的值为获取的解密的token

(10)根据用户是否定义tokenKey设置ctx.state的tokenKey属性的值为获取token的函数。

(11)执行后面的组件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言大作业_2018 C语言大作业--21_Ekko制作教程

同学们实现的效果:https://www.zhihu.com/video/1066249425780809728以下是开发同学的相关文档:《Ekko》设计报告本组设计并编写的游戏《Ekko》,是一款引用了当下红火的网络游戏《英雄联盟》中的游戏角色Ekko为主角,由本组三名成员…

Nutshell中的Java 8语言功能-第1部分

你好朋友, Java 8发布已经很长时间了,现在越来越多地被使用。 在本文中,我们将讨论以下Java 8主题。 1.功能接口 2,Lambda表达式 3.默认方法 1.功能界面 什么是功能接口? 与一种并且只有一种抽象方法的接口是功能…

做ppt用的小插图_如何用PPT做随机抽奖?

每到年底,每个公司都开始筹备年会活动。年会在员工们最期待的就是抽奖环节了。除了用专门的抽奖软件之外,PPT也可以做随机抽奖。今天就来解锁这个动画的做法。1,先设置好图片和文本;2,选中每一张幻灯片,选择…

mysql 隔离级别 快照_MySql的四种事务隔离级别

一、事务的四大特性(ACID)了解事务隔离级别之前不得不了解的事务的四大特性。1、原子性(Atomicity)事务开始后所有操作,要么全部做完,要么全部不做。事务是一个不可分割的整体。事务在执行过程中出错,会回滚到事务开始之前的状态,…

jsp mysql论坛_使用SSM和ajax做一个简易的论坛-01(简介和建表)

三月底刚学完SSM试着做了个简单的论坛,想分享一下,顺便整理一下自己的收获。一、demo介绍一个具有登录、注册功能,发帖、回帖功能的简易论坛。没有后台系统。设计逻辑类似于贴吧,发帖时自动附带一个一楼。二、使用的框架/库前端&a…

elastic 修改map_Amazon Elastic Map Reduce使用Apache Mahout计算建议

elastic 修改mapApache Mahout是一个“可扩展的机器学习库”,其中包括各种单节点和分布式推荐算法的实现。 在上一篇博客文章中, 我描述了如何在单个节点上实现在线推荐系统来处理数据。 如果数据太大而无法放入内存(> 100M首选项数据点&a…

mysql 更新时间加数字_Mysql实战45讲笔记:8、聚合函数count

count(*)的实现方式在不同的MySQL引擎中,count()有不同的实现方式 1. MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count()的时候会直接返回这个数,效率很高; 2. 而InnoDB引擎就麻烦了,它执行count(*)的时候&…

python学生管理系统类图_类图 python

广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 我正在研究一个庞大的遗留python类,它有很多方法。 我最终将复杂的方法分解成更小的部分&#x…

简单的测试可以防止最严重的故障

错误处理是软件开发中最困难且被忽略的部分之一,如果系统是分布式的,那么这将变得更加困难。 好的论文写在“ 简单测试可以预防最关键的故障” 主题上。 每个开发人员都应该阅读本文。 我将尝试总结本文的主要内容,但建议阅读该论文以获取有…

sql 两个 in_SQL基础知识——IN运算符

IN的作用IN运算符允许您在WHERE子句中指定多个值。IN运算符是多个OR条件的简写。IN的语法SELECT column_name(s) FROM table_name WHERE column_name IN (value1, value2, ...);或者SELECT column_name(s) FROM table_name WHERE column_name IN (SELECT STATEMENT);示例数据库…

pythonlist循环添加元素_python中 for循环之后 添加元素到列表失败?

import re ls list() dc dict() # 介词、连词、人称代词等自己统计 adverb [i, you, he, she, it, in, on, with, by, for, at, about, under, of, to, and, or, therefore, so, of, a] with open("老人与海.txt", moder, encodingutf-8) as f: lryh f.read() # …

开始协议处理句柄_基于smb协议的wmiexec浅析

前言之前研究过Crackmapexec这款工具,对这个工具基于smb协议的wmiexec执行方法产生的流量进行了分析,网上似乎还没有相关的文章,这里旨在抛砖引玉,简单梳理下整个过程,以初学者的视角,探索流量当中存在的奥…

apache camel_轻量级的开源集成:Apache Camel还是Spring集成?

apache camel首先,为全面披露信息,在过去的1.5年中, 我一直担任 FuseSource(现为Red Hat) 的顾问,为零售,运输,银行/金融等不同行业的大型和小型公司提供SOA和集成项目支持。我的专长…

科尔达服务101

我今天想写一篇简短的要点文章。 我真的很好奇我能多快出版此书。 所以走吧 这篇文章是关于Corda Services(使用Corda 3.2版)的。 这些是什么? 作为经常使用Spring的开发人员,我个人会说它们就像Beans。 Spring Beans可以做的还很…

intent隐式和显式_Neo4j:使隐式关系成为显式和双向关系

intent隐式和显式我最近阅读了Michal Bachman关于 Neo4j中双向关系的文章 ,他建议对于某些关系类型,我们对关系的方向不那么感兴趣,因此可以在查询时忽略它。 他使用以下示例显示Neo Technology和GraphAware之间的合作关系: 两家…

mysql读写分离 存储过程_基于maxscale的读写分离部署笔记

使用maxscale搭建的读写分离架构,后期还可以再结合MHA做master的故障转移,这样业务层面上不需要做任何的改动即可。基于connect方式的不要使用。从库延迟他还会继续分发请求过去,暂时不适合生产使用。实验演示:目前的主从结构&…

python读书笔记2000_流畅的Python读书笔记

特殊方法的存在是为了Python解释器调用的,你自己并不需要去调用他们,比如说my_object.len()这种写法是没有的,应该使用len(my_object)。在使用len(my_object)的时候,如果my_object是一个自定义类的对象,那么Python会自…

antd 3升级命令_是时候拥有一个你自己的命令行工具了

本篇博客主要介绍了如何使用commander, inquirer以及chalk从零开始,创建属于自己的命令行工具。0. 一分钟体验首先我们先花一分钟的时间,体验一下创建自己的命令行cli工具是什么感觉。0.1. 新建项目目录假如我们的项目名称叫hello-cli,使用如…

找不到要去的声明_老汉将行李袋交由他人看管 去了一趟卫生间找不到人了.........

春节走亲访友难免多喝两杯,但酒后乘车却容易造成财物遗失。目前正值春运返程高峰,从沧州女儿家返程回山东老家的蔡先生就因为中午多喝了几杯酒,便将装有12000元生活费的行李袋弄丢了。好在沧州火车站派出所民警最终将蔡先生的失物找回&#x…

java可视化压缩_web可视化技术发展(1/6)

EverCraft一直在关注Web可视化技术的发展,在本系列文章里,小编将对国外一篇感觉很不错的综述性文章进行翻译,供这一领域的爱好者相互学习。这篇paper的信息为:“Mwalongo, F., et al., State-of-the-Art Report in Web-based Visu…