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

代码地址以下:<br>http://www.demodashi.com/demo/13847.htmlhtml

运行环境

该项目基于 node(v7.8.0版本以上) 和 mongodb 数据库,所以电脑上须要安装这两个软件,安装教程自行百度。mongodb教程。若是实在不懂安装,请勿下载代码。前端

运行项目

此处已表明已经安装完成了node和mongodb,下载代码以后,目录结构是这样子的: vue

接下来须要安装依赖,执行 npm install,完成以后,目录结构下多了一个 node_modules 的目录,这些就是依赖文件。node

接下来运行 mongodb服务,而后在项目根目录下执行 node app.js,运行node服务,而后在浏览器打开 http://localhost:3000 ,则能够正常访问了。 若是想修改页面,能够再执行 npm run serve,运行 vue,访问 http://localhost:8080 ,就能够了ios

需求分析

在先后端分离的开发中,经过 Restful API 进行数据交互时,若是没有对 API 进行保护,那么别人就能够很容易地获取并调用这些 API 进行操做。那么服务器端要如何进行鉴权呢?web

Json Web Token 简称为 JWT,它定义了一种用于简洁、自包含的用于通讯双方之间以 JSON 对象的形式安全传递信息的方法。JWT 可使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名。算法

因此,咱们要给 API 加上 JWT 认证。mongodb

实现过程

首先用户登陆时,输入用户名和密码后请求服务器登陆接口,服务器验证用户名密码正确后,生成token并返回给前端,前端存储token,并在后面的请求中把token带在请求头中传给服务器,服务器验证token有效,返回正确数据。 数据库

代码实现

生成token

这里注册了个 /login 的路由,用于用户登陆时获取token。npm

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

代码地址以下:<br>http://www.demodashi.com/demo/13847.html

注:本文著做权归做者,由demo大师代发,拒绝转载,转载须要做者受权