Node.js使用JWT进行用户认证
node.js 使用 jwt 进行用户认证
运行环境
该项目基于 node(v7.8.0版本以上) 和 mongodb ,因此电脑上需要安装这两个软件,安装教程自行百度。mongodb教程。如果实在不懂安装,请勿下载代码。
运行项目
此处已代表已经安装完成了node和mongodb,下载代码之后,目录结构是这样子的:
接下来需要安装依赖,执行 npm install,完成之后,目录结构下多了一个 node_modules 的目录,这些就是依赖文件。
接下来运行 mongodb服务,然后在项目根目录下执行 node app.js,运行node服务,然后在打开 https://localhost:3000 ,则可以正常访问了。
如果想修改页面,可以再执行 npm run serve,运行 vue,访问 https://localhost:8080 ,就可以了
需求分析
在前后端分离的开发中,通过 restful api 进行数据交互时,如果没有对 api 进行保护,那么别人就可以很容易地获取并调用这些 api 进行操作。那么服务器端要如何进行鉴权呢?
json web token 简称为 jwt,它定义了一种用于简洁、自包含的用于通信双方之间以 json 对象的形式安全传递信息的方法。jwt 可以使用 hmac 算法或者是 rsa 的公钥密钥对进行签名。
所以,我们要给 api 加上 jwt 认证。
实现过程
首先用户登录时,输入用户名和密码后请求服务器登录接口,服务器验证用户名密码正确后,生成token并返回给前端,前端存储token,并在后面的请求中把token带在请求头中传给服务器,服务器验证token有效,返回正确数据。
代码实现
生成token
这里注册了个 /login 的路由,用于用户登录时获取token。
const router = require('koa-router')(); const jwt = require('jsonwebtoken'); const usermodel = require('../models/usermodel.js'); router.post('/login', async (ctx) => { const data = ctx.request.body; if(!data.name || !data.password){ return ctx.body = { code: '000002', data: null, msg: '参数不合法' } } const result = await usermodel.findone({ name: data.name, password: data.password }) if(result !== null){ const token = jwt.sign({ name: result.name, _id: result._id }, 'my_token', { expiresin: '2h' }); return ctx.body = { code: '000001', data: token, msg: '登录成功' } }else{ return ctx.body = { code: '000002', data: null, msg: '用户名或密码错误' } } }); module.exports = router;
在验证了用户名密码正确之后,调用 jsonwebtoken 的 sign() 方法来生成token,接收三个参数,第一个是载荷,用于编码后存储在 token 中的数据,也是验证 token 后可以拿到的数据;第二个是密钥,自己定义的,验证的时候也是要相同的密钥才能解码;第三个是options,可以设置 token 的过期时间。
获取token
接下来就是前端获取 token,这里是在 vue.js 中使用 axios 进行请求,请求成功之后拿到 token 保存到 localstorage 中。这里登录成功后,还把当前时间存了起来,除了判断 token 是否存在之外,还可以再简单的判断一下当前 token 是否过期,如果过期,则跳登录页面
submit(){ axios.post('/login', { name: this.username, password: this.password }).then(res => { if(res.code === '000001'){ localstorage.setitem('token', res.data); localstorage.setitem('token_exp', new date().gettime()); this.$router.push('/'); }else{ alert(res.msg); } }) }
然后请求服务器端api的时候,把 token 带在请求头中传给服务器进行验证。每次请求都要获取 localstorage 中的 token,这样很麻烦,这里使用了 axios 的请求拦截器,对每次请求都进行了取 token 放到 headers 中的操作。
axios.interceptors.request.use(config => { const token = localstorage.getitem('token'); config.headers.common['authorization'] = 'bearer ' + token; return config; })
验证token
通过 koa-jwt 中间件来进行验证,用法也非常简单
const koa = require('koa'); const koajwt = require('koa-jwt'); const app = new koa(); // 错误处理 app.use((ctx, next) => { return next().catch((err) => { if(err.status === 401){ ctx.status = 401; ctx.body = 'protected resource, use authorization header to get access\n'; }else{ throw err; } }) }) app.use(koajwt({ secret: 'my_token' }).unless({ path: [/\/user\/login/] }));
通过 app.use 来调用该中间件,并传入密钥 {secret: 'my_token'},unless 可以指定哪些 url 不需要进行 token 验证。token 验证失败的时候会抛出401错误,因此需要添加错误处理,而且要放在 app.use(koajwt()) 之前,否则不执行。
如果请求时没有token或者token过期,则会返回401。
运行效果
登陆
获取用户信息
无效请求
node.js 使用 jwt 进行用户认证
推荐阅读
-
前后端分离之JWT用户认证
-
记一次在node.js中使用crypto的createCipheriv方法进行加密时所遇到的坑
-
ASP.NET Core 2.2 : 二十六. 应用JWT进行用户认证及Token的刷新
-
Node.js使用supervisor进行开发中调试的方法
-
关于opensips用户认证配置文件 opensips.cfg 使用介绍
-
在.NET Core中使用Jwt对API进行认证
-
ASP.Net Core 3.1 中使用JWT认证
-
Nginx中的用户认证配置及阻止用户使用代理访问的方法
-
详解Spring Boot实战之Filter实现使用JWT进行接口认证
-
PHP如何使用JWT做Api接口身份认证的实现