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


    代码地址如下:
    http://www.demodashi.com/demo/13847.html

    运行环境

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

    运行项目

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

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

    接下来运行 mongodb服务,然后在项目根目录下执行 node app.js,运行node服务,然后在浏览器打开 http://localhost:3000 ,则可以正常访问了。
    如果想修改页面,可以再执行 npm run serve,运行 vue,访问 http://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
    ';
            }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 进行用户认证

    代码地址如下:
    http://www.demodashi.com/demo/13847.html

    注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

  • 相关阅读:
    JDBC batch批处理Statement executeBatch 具体解释
    NGUI字体贴图压缩以及相关Shader解读
    埃博拉患者的死亡经历
    Android URI简单介绍
    【安卓笔记】通过发送特定的短信远程控制手机
    InstallShield12豪华版破解版下载|InstallShield下载|软件打包工具
    求平方根C++
    监听手机录音
    My安装EclipseJS代码提示(Spket插件)
    四个好看的CSS样式表格
  • 原文地址:https://www.cnblogs.com/demodashi/p/9582502.html
Copyright © 2020-2023  润新知