本文转自:https://blog.csdn.net/qq673318522/article/details/78641136

关于 Token 认证机制,这里不做更多解释。不清楚的可以看我的这篇文章:Web开发中常见的认证机制
GitHub 地址:koa-jwt-sample

所需库
bcrypt - 用于加密密码
koa-jwt - jwt 中间件
jsonwebtoken - 用于生成token下发给浏览器,在 koa2 以后的版本不再提供 jsonwebtoken 的方法,所以需要另行安装。
实现思路
整个方案实现的流程和思路很清晰,大致分为下面几步:
- 自定义 401 拦截中间件,用于拦截 token 不存在或者失效的情况
- 配置 koa-jwt
- 注册实现
- 登录实现

运行项目
该项目需要你已经装好 mongodb,并启动。关于 mongodb 的配置见 config/index.js。

npm run start
1
该项目提供了三个 api
- /api/register
- /api/login
- /api/users

其中 /api/register 和 /api/login 为 public api,无需token就能访问。/users 则为 private api,需要传入正确的 token 才能访问。

自定义 401 handler
使用了 koa-jwt 中间件后,如果没有token,或者token失效,该中间件会给出对应的错误信息。如果没有自定义中间件的话,会直接将 koa-jwt 暴露的错误信息直接返回给用户。

// server/middlewares/errorHandle.js
export default errorHandle = (ctx, next) => {
return next().catch((err) => {
if (err.status === 401) {
ctx.status = 401;
ctx.body = {
error: err.originalError ? err.originalError.message : err.message,
};
} else {
throw err;
}
});
}

然后在 index.js 中使用该中间件

app
.use(errorHandle)

使用 koa-jwt
在 index.js 中加入 koa-jwt 中间件。

const secert = 'jwt_secret'
app
.use(jwt({
secret,
}).unless({
path: [/\/register/, /\/login/],
}))

其中 secret 是用于加密的key,不局限于字符串,也可以是一个文件。

// https://github.com/koajs/jwt#token-verification-exceptions
var publicKey = fs.readFileSync('/path/to/public.pub');
app.use(jwt({ secret: publicKey }));

unless() 用于设置哪些 api 是不需要通过 token 验证的。也就是我们通常说的 public api,无需登录就能访问的 api。在这个例子中,设置了 /register 和 /login 两个 api 无需 token 检查。

在使用 koa-jwt 后,所有的路由(除了 unless() 设置的路由除外)都会检查 Header 首部中的 token,是否存在、是否有效。只有正确之后才能正确的访问。

注册实现
注册很简单,这里只是简单的将密码加密,将信息存入数据库。实际项目中,还需要对用户输入的字段进行验证。

/**
* you can register with
* curl -X POST http://localhost:3200/api/register -H 'cache-control: no-cache' -H 'content-type: application/x-www-form-urlencoded' -d 'username=superman2&password=123456'
*/
async register(ctx) {
const { body } = ctx.request;
try {
if (!body.username || !body.password) {
ctx.status = 400;
ctx.body = {
error: `expected an object with username, password but got: ${body}`,
}
return;
}
body.password = await bcrypt.hash(body.password, 5)
let user = await User.find({ username: body.username });
if (!user.length) {
const newUser = new User(body);
user = await newUser.save();
ctx.status = 200;
ctx.body = {
message: '注册成功',
user,
}
} else {
ctx.status = 406;
ctx.body = {
message: '用户名已经存在',
}
}
} catch (error) {
ctx.throw(500)
}
}

登录实现
用户输入用户名和密码登录,如果用户名和密码正确的话,使用 jsonwebtoken.sign() 生成 token,并返回给客户端。客户端将token存储在本地存储,在每次的 HTTP 请求中,都将 token 添加在 HTTP Header Authorazition: Bearer token 中。然后后端每次去验证该token的正确与否。只有token正确后才能访问到对应的资源。

/** you can login with
* curl -X POST http://localhost:3200/api/login/ -H 'cache-control: no-cache' -H 'content-type: application/x-www-form-urlencoded' -d 'username=superman2&password=123456'
*/
async login(ctx) {
const { body } = ctx.request
try {
const user = await User.findOne({ username: body.username });
if (!user) {
ctx.status = 401
ctx.body = {
message: '用户名错误',
}
return;
}
// 匹配密码是否相等
if (await bcrypt.compare(body.password, user.password)) {
ctx.status = 200
ctx.body = {
message: '登录成功',
user: user.userInfo,
// 生成 token 返回给客户端
token: jsonwebtoken.sign({
data: user,
// 设置 token 过期时间
exp: Math.floor(Date.now() / 1000) + (60 * 60), // 60 seconds * 60 minutes = 1 hour
}, secret),
}
} else {
ctx.status = 401
ctx.body = {
message: '密码错误',
}
}
} catch (error) {
ctx.throw(500)
}
}

需要注意的是,在使用 jsonwebtoken.sign() 时,需要传入的 secret 参数,这里的 secret 必须要与 前面设置 jwt() 中的 secret 一致。

更多关于 jsonwebtoken 的方法,可见:https://github.com/auth0/node-jsonwebtoken

在登录后,拿着返回的 token,这时候去访问 /api/users,就能正确获得用户列表。

curl -X GET http://localhost:3200/api/users -H 'authorization: Bearer token' -H 'cache-control: no-cache'
---------------------
作者:前端超人
来源:CSDN
原文:https://blog.csdn.net/qq673318522/article/details/78641136
版权声明:本文为博主原创文章,转载请附上博文链接!

[转]koa 实现 jwt 认证的更多相关文章

  1. sau交流学习社区--songEagle开发系列:Vue.js + Koa.js项目中使用JWT认证

    一.前言 JWT(JSON Web Token),是为了在网络环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519). JWT不是一个新鲜的东西,网上相关的介绍已经非常多了.不是很了解的 ...

  2. 个人博客开发系列:Vue.js + Koa.js项目中使用JWT认证

    前言 JWT(JSON Web Token),是为了在网络环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519). 更多的介绍和说明,以及各种原理,我在此就不多赘诉了.JWT不是一个新鲜 ...

  3. KoaHub平台基于Node.js开发的Koa JWT认证插件代码信息详情

    koa-jwt Koa JWT authentication middleware. koa-jwt Koa middleware that validates JSON Web Tokens and ...

  4. 使用python实现后台系统的JWT认证(转)

    今天的文章介绍一种适用于restful+json的API认证方法,这个方法是基于jwt,并且加入了一些从oauth2.0借鉴的改良. 1. 常见的几种实现认证的方法 首先要明白,认证和鉴权是不同的.认 ...

  5. Asp.Net Core基于JWT认证的数据接口网关Demo

    近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对 ...

  6. Laravel 中使用 JWT 认证的 Restful API

    Laravel 中使用 JWT 认证的 Restful API 5天前/  678 /  3 / 更新于 3天前     在此文章中,我们将学习如何使用 JWT 身份验证在 Laravel 中构建 r ...

  7. JWT 认证 以及Django 中的应用

    jwt 认证 私钥.公钥.CA认证 用一套加密规则 加密和解密 RSA加密 (非对称的加密) 摘要算法:MD5 FTP/互联网下载软件校验MD5 私钥 --RSA算法-->公钥 RSA原理 加密 ...

  8. asp.net core 自定义401和异常显示内容(JWT认证、Cookie Base认证失败显示内容)

    asp.net core 2.0使用JWT认证园子里已经有挺多帖子了,但开发中发现认证未授权情况下返回的401状态码是没有任何信息的,业务中可能有需要返回一串错误的Json信息.在这里我分享一个自定义 ...

  9. Asp.net Core认证和授权:JWT认证和授权

    JWT验证一般用户移动端,因为它不像cookie验证那样,没有授权跳转到登陆页面 JWT是json web token的简称,在  jwt.io 网址可以看到 新建一个API项目,通过postman ...

随机推荐

  1. python 安装cv2

    问题描述:import cv2 报错提示未安装此包. 解决措施: 1.cmd框中输入pip install cv2,若安装成功,则恭喜你一次性成功,如提示"无法找到与你当前版本的匹配&quo ...

  2. Java关于static的作用

    概述 只要是有学过Java的都一定知道static,也一定能多多少少说出一些作用和注意事项.如果已经对static了如指掌的请点击关闭按钮,看下去也只是浪费您宝贵时间而已.这篇随笔只是个人的习惯总结. ...

  3. vue.js - 奇怪的 event 对象

    好久都没有写点东西了, 前段时间工作搞得头大,真的就是一起加班到死了.废话不多说,写这篇文章是因为这次因为 event 对象闹了一个乌龙,以此总结一下. 一.event 对象 (一)事件的 event ...

  4. python接口自动化(二十)--token登录(详解)

    简介 为了验证用户登录情况以及减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮.有些登录不是用 cookie 来验证的,是用 token 参数来判断是否登录.token 传参有两种一种是放在请 ...

  5. RabbitMQ的介绍及使用进阶(Docker+.Net Core)

    目录: 一.什么是RabbitMQ 二.RabbitMQ运用场景 三.RabbitMQ优势及特点 四.Centos7中Docker安装RabbitMQ 五..Net Core 中使用RabbitMQ ...

  6. 学习笔记02(随便看看mybatis源码)

    两个很有名的持久层hibernate和mybatis应该很熟悉不过了,两者最大相同点是底层都是对jdbc的封装,最大的不同点是前者是自动生成sql语句,后者是需要我们在映射文件中写出sql. 其实从以 ...

  7. 学习 JavaScript (四)核心概念:操作符

    JavaScript 的核心概念主要由语法.变量.数据类型.操作符.语句.函数组成,前面三个上一篇文章已经讲解完了.后面三个内容超级多,这篇文章主要讲解的是操作符. 操作符 什么叫做操作符? 这是一种 ...

  8. Docker安装+HelloWorld+运行Tomcat

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 上一篇已经讲解了为什么需要Docker?,相信大家已 ...

  9. 解决 VS2019 打开 edmx 文件时没有 Diagram 视图的 Bug

    问题描述 安装 VS 2019 (版本:16.0.2)后,发现更新选项中已经没有 “Entity Framework 6.X 工具” 了,打开 .edmx 文件时,呈现的视图是 xml 视图. 解决方 ...

  10. vue 使用 supermap iclient-classic

    1. 2.在组件中: import "@supermap/iclient-classic/libs/SuperMap-8.1.1-16520"; import { MapVLaye ...