欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Node.js使用JWT进行用户认证

程序员文章站 2022-04-30 18:05:30
node.js 使用 jwt 进行用户认证 运行环境 该项目基于 node(v7.8.0版本以上) 和 mongodb ,因此电脑上需要安装这两个软件,安装教程自行百度。mongodb教程。如果实在...

node.js 使用 jwt 进行用户认证

运行环境

该项目基于 node(v7.8.0版本以上) 和 mongodb ,因此电脑上需要安装这两个软件,安装教程自行百度。mongodb教程。如果实在不懂安装,请勿下载代码。

运行项目

此处已代表已经安装完成了node和mongodb,下载代码之后,目录结构是这样子的:
Node.js使用JWT进行用户认证

接下来需要安装依赖,执行 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有效,返回正确数据。
Node.js使用JWT进行用户认证

代码实现

生成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进行用户认证

获取用户信息

Node.js使用JWT进行用户认证

无效请求

Node.js使用JWT进行用户认证node.js 使用 jwt 进行用户认证