详解Node.js使用token进行认证的简单示例


Posted in Javascript onMay 25, 2020

本文只介绍简单的应用,关于json web token的具体介绍以及原理请参考阮一峰老师的JSON Web Token 入门教程。

使用的Node框架是koa2,前端发送ajax请求使用axios

首先创建工程目录:

详解Node.js使用token进行认证的简单示例

static中存放静态资源,views存放前端模板,server.js为后端代码。

安装必要的依赖项:

"dependencies": {
  "@koa/router": "^8.0.8",
  "jsonwebtoken": "^8.5.1",
  "koa": "^2.12.0",
  "koa-bodyparser": "^4.3.0",
  "koa-ejs": "^4.3.0",
  "koa-jwt": "^4.0.0",
  "koa-static": "^5.0.0",
  "koa-views": "^6.2.2"
 }

在server.js中添加代码来创建一个简单的后端程序,由于网上有太多相关示例代码,在此不再赘述。

const koa = require('koa');
const app = new koa();
const bodyParser = require('koa-bodyparser');
const router = require('@koa/router')();
const views = require('koa-views');
const static = require('koa-static');
const path = require('path');

app.use(bodyParser());
app.use(views(__dirname + '/views', {
 map: { html: 'ejs' }
}));

app.use(static(path.join(__dirname, '/static')));

router.get('/', ctx => ctx.render('index'));

app
 .use(router.routes())
 .use(router.allowedMethods());

app.listen(8080, () => {
 console.log('server is running at port 8080');
});

const path = require('path');后添加代码:

const { sign } = require('jsonwebtoken');
const secret = 'demo';
const jwt = require('koa-jwt')({ secret });

sign方法用来生成toekn,secret为自定义的秘钥,jwt提供路有权限控制的功能,它会对需要限制的资源请求进行检查。

创建路由login:

router.post('/login', ctx => {
 const { user } = ctx.request.body;
 if (user && user.username === 'vip') {
  let { username } = user;
  const token = sign({ username }, secret, { expiresIn: '1h' });
  ctx.body = {
   message: 'GET TOKEN SUCCESS',
   status: 200,
   token
  }
 } else {
  ctx.body = {
   message: 'GET TOKEN FAILED',
   status: 500
  }
 }
});

如代码所示,当前端发送的请求体中包含一个user对象并且username为vip时将生成一个token返回给前端,这里用到了前文提到的sign方法,第一个参数是用户信息,第二个参数是自定义的key,第三个参数是个option,此处只定义了过期时间。

再创建路由info:

router.get('/info', jwt, ctx => {
 ctx.body = { message: `Welcome ${ctx.state.user.username}!`};
});

与平时看到的路由代码稍有不同,这里增加了一个jwt中间件,用来对权限进行控制,如果无法通过验证,则不会执行之后的代码。在前文生成token后,会把用户名存入ctx.state.user中,在这里可以直接获取。

这时在控制台中输入node server启动该项目

打开index.html文件,添加一个简单的表单和一个按钮,并引入axios:

<form>
 <input type="text" name="username">
 <button id="submit">提交</button>
</form>
<button id="get">获取</button>
<script src="/vendors/axios.min.js"></script>

首先添加登录的逻辑:

document.querySelector('#submit').addEventListener('click', e => {
  e.preventDefault();
  const username = document.querySelector('input[name="username"]').value;
  axios.post('/login', { user: { username } })
   .then(response => {
    response = response.data;
    const { status, token, message } = response;
    if (status === 200) {
     localStorage.setItem('token', token);
    }
    alert(message);
   })
   .catch(error => alert(error.toString()));
 });

这里将服务端生成的token存入localStorage以便下次使用。

当在输入框中输入vip并点击提交按钮,后端返回如下格式的信息:

message: "GET TOKEN SUCCESS"
status: 200
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InZpcCIsImlhdCI6MTU5MDMyOTkxOSwiZXhwIjoxNTkwMzMzNTE5fQ.PsyLYmr-pDxxdtrBEvMccVtBr9-xtOAHdZKen4FP34c"

然后再添加获取逻辑:

document.querySelector('#get').addEventListener('click', e => {
  e.preventDefault();
  const instance = axios.create({ headers: { authorization: `Bearer ${localStorage.getItem('token')}` } });
  instance.get('/info')
   .then(response => {
    response = response.data;
    console.log(response)
    alert(response.message);
   })
   .catch(error => alert(error.toString()));
 });

此处用到了axios.create方法,该方法可以在请求头中添加token信息。用localStorage中获取token并拼成形如authorization: Bearer token的形式,然后再用示例发送get请求。

此时再点击获取按钮,会提示:

详解Node.js使用token进行认证的简单示例

证明token是有效的。

此时去Application中把localStorage记录清除掉,再点击获取按钮,提示:

详解Node.js使用token进行认证的简单示例

证明拦截成功。

完整示例可以去我的GitHub查看并下载。

到此这篇关于详解Node.js使用token进行认证的简单示例的文章就介绍到这了,更多相关Node.js使用token认证内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
用Javascript 和 CSS 实现脚注(Footnote)效果
Sep 09 Javascript
javascript定时保存表单数据的代码
Mar 17 Javascript
javascript模拟select,jselect的方法实现
Nov 08 Javascript
Ajax异步提交表单数据的说明及方法实例
Jun 22 Javascript
jQuery bt气泡实现悬停显示及移开隐藏功能的方法
Jul 12 Javascript
利用Js的console对象,在控制台打印调式信息测试Js的实现
Nov 26 Javascript
JS常用知识点整理
Jan 21 Javascript
ES6学习之变量的解构赋值
Feb 12 Javascript
VUE页面中加载外部HTML的示例代码
Sep 20 Javascript
mpvue 单文件页面配置详解
Dec 02 Javascript
深入理解使用Vue实现Context-Menu的思考与总结
Mar 09 Javascript
Node.js学习教程之Module模块
Sep 03 Javascript
基于redis的小程序登录实现方法流程分析
May 25 #Javascript
JSONP解决JS跨域问题的实现
May 25 #Javascript
JS实现时间校验的代码
May 25 #Javascript
使用Typescript和ES模块发布Node模块的方法
May 25 #Javascript
js 动态校验开始结束时间的实现代码
May 25 #Javascript
使用 Opentype.js 生成字体子集的实例代码详解
May 25 #Javascript
Node.js API详解之 repl模块用法实例分析
May 25 #Javascript
You might like
兼容firefox,chrome的网页灰度效果
2011/08/08 PHP
浅析PKI加密解密 OpenSSL
2013/07/01 PHP
Laravel 的数据库迁移的方法
2017/07/31 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
2020/03/26 PHP
扩展String功能方法
2006/09/22 Javascript
JavaScript While 循环基础教程
2007/04/05 Javascript
初窥JQuery-Jquery简介 入门了解篇
2010/11/25 Javascript
js 通用订单代码
2013/12/23 Javascript
JavaScript代码复用模式详解
2014/11/07 Javascript
JavaScript的内存释放问题详解
2015/01/21 Javascript
JS获取网页图片name属性的方法
2015/04/01 Javascript
完美解决spring websocket自动断开连接再创建引发的问题
2017/03/02 Javascript
详解node HTTP请求客户端 - Request
2017/05/05 Javascript
详解Vue 如何监听Array的变化
2019/06/06 Javascript
js实现自动播放匀速轮播图
2020/02/06 Javascript
JS实现页面数据懒加载
2020/02/13 Javascript
JavaScript使用prototype属性实现继承操作示例
2020/05/22 Javascript
[36:19]2018DOTA2亚洲邀请赛 小组赛 A组加赛 Newbee vs LGD
2018/04/03 DOTA
python判断端口是否打开的实现代码
2013/02/10 Python
Python中的defaultdict模块和namedtuple模块的简单入门指南
2015/04/01 Python
Python多线程编程(五):死锁的形成
2015/04/05 Python
django 信号调度机制详解
2019/07/19 Python
centos7中安装python3.6.4的教程
2019/12/11 Python
python scrapy重复执行实现代码详解
2019/12/28 Python
详解Ubuntu环境下部署Django+uwsgi+nginx总结
2020/04/02 Python
jupyter修改文件名方式(TensorFlow)
2020/04/21 Python
open_basedir restriction in effect. 原因与解决方法
2021/03/14 PHP
CSS3实现粒子旋转伸缩加载动画
2016/04/22 HTML / CSS
HTML5 层的叠加的实现
2020/07/07 HTML / CSS
哥伦比亚加拿大官网:Columbia Sportswear Canada
2020/09/07 全球购物
在网络中有两台主机A和B,并通过路由器和其他交换设备连接起来,已经确认物理连接正确无误,怎么来测试这两台机器是否连通?如果不通,怎么来判断故障点?怎么排
2014/01/13 面试题
农村产权制度改革实施方案
2014/03/21 职场文书
绿色小区申报材料
2014/08/22 职场文书
幼儿园教师个人工作总结2015
2015/05/12 职场文书
2016年大学生就业指导课心得体会
2015/10/09 职场文书
weblogic服务建立数据源连接测试更新mysql驱动包的问题及解决方法
2022/01/22 MySQL