node脚手架搭建服务器实现token验证的方法


Posted in Javascript onJanuary 20, 2021

内容

  • 用脚手架快速搭建 node 项目
  • 用 mysql 连接池实现与数据库的交互
  • 用 jsonwebtoken 实现 token 身份验证
  • 综合案例:用简介登录页面实现上述内容

1. 快速搭建 node 项目

我们都知道 express 框架可高效的开发 node 服务器,但对于底层的搭建还要靠自己手写。然而 express-generator 的出现就很好地解决了此问题,它可一键为我们生成项目基本骨架,可谓node 脚手架

1.1 生成项目

①:首先全局安装 express : npm install express -g
②:接着全局安装 express-generator:npm install express-generator -g
③:然后使用命令创建项目: express token_learn(项目名称)

1.2 修改入口文件

对于好多习惯了手撸服务器的人,app.js 总是让人难忘,奈何此骨架中入口文件为 www.js。此时我们可以手动修改app.js 代码,让其成为我们的入口文件

示例:

var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');

const index = require('./routes/index');
const users = require('./routes/users');

const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);
app.use('/users', users);

app.listen(3000, () => console.log('server is run 3000'))

2. 连接mysql 数据库

此处采用连接池的方式进行连接(高效安全)

2.1 创建连接

①:安装 mysql 模块:npm i mysql
②:在项目根目录下配置连接池

首先在项目根目录下创建 util 文件夹,文件夹下创建 bdconfig.js 文件

bdconfig.js

const mysql = require('mysql');

module.exports = {
  mysqlParams: {
    host: 'localhost', //域名
    port: '3306', //端口
    user: 'root', //用户名
    password: 'myroot', //密码
    database: 'nodeapi' //数据库
  },
  sySqlConnect(sql, sqlArr) {
    return new Promise((resolve, reject) => { //用Promise对象将其改造,方便接收数据
      const pool = mysql.createPool(this.mysqlParams);
      pool.getConnection((err, conn) => {
        if (err) {
          reject(err)
        } else {
          conn.query(sql, sqlArr, (err, data) => { //操作数据库
            if (err) {
              reject(err)
            } else {
              resolve(data)
            }
          })
          conn.release() //释放连接
        }
      })
    })
  }
}

2.2 使用连接

使用时只需要传入 sql(sql语句)、sqlArr(参数),通过Promise 改造后可直接用返回值拿到结果

3. token 身份验证

随着web 的发展,session、cookie 的验证方式弊端也愈发突出,此时token孕育而生,token的强大不仅限于其是无状态的,还在于它可以跨域

3.1 实现步骤

①:首先安装 jsonwebtoken 模块:npm i jsonwebtoken
②:接着在项目中使用该模块

const dbConfig = require('../util/dbconfig');
const jwt = require('jsonwebtoken');
const secret = 'login-rule'; //秘钥规则(自定义)

token = async(req, res, next) => { //定义token验证中间件函数(应用于除登录外的每个请求)
  if (req.headers.authorization) {
    const token = req.headers.authorization;
    const { id, username } = jwt.verify(token, secret); // 对token进行解密查找
    let sql = 'select * from test where id=?';
    let sqlArr = [id];
    let result = await dbConfig.sySqlConnect(sql, sqlArr);
    if (result.length === 0) {
      res.status(200).send({ msg: '用户错误' })
      return
    }
    if (username !== result[0].username) {
      res.status(200).send({ msg: '用户错误' })
    } else {
      next()
    }
  } else {
    res.status(200).send({ msg: '无效请求头' })
  }
}

login = async(req, res) => { //定义登录接口(因为这个请求头不携带token,所以引用在token验证中间件之前)
  let { username, password } = req.body;
  let sql = 'select * from test where username=?';
  let sqlArr = [username];
  let result = await dbConfig.sySqlConnect(sql, sqlArr);
  if (result.length) {
    if (password === result[0].password) {
      const { id, username } = result[0];
      //对token进行加密响应个客户端(参数1:传值规则;参数2:加密规则; 参数3:定义时间)
      const token = jwt.sign({ id, username }, secret, { expiresIn: 60 * 60 });
      res.status(200).send({ msg: '登陆成功', token: token, status: 200 });
    } else {
      res.status(200).send({ msg: '登陆失败', status: 422 });
    }
  } else {
    res.status(200).send({ msg: '用户名不存在', status: 401 })
  }
}

// 验证身份中间件
module.exports = {
  token,
  login
}

③:在 app.js 中进行配置

// 写在 app.use() 之后,路由之前
app.use('/users/loginjwt', token.login); //登录接口(无需验证token,所以写在token中间件之前)
app.use(token.token);

4. 案例实现 token

4.1 原理阐述

为确保身份唯一且有效:用户每次发送登录请求且登录成功,服务器端都会响应给用户一个含用户信息(唯一)的加密 token(字符串),此时用户接收到 token,并把 token 存储在 sessionStorage 或 localStorage中(此处为)。同时用户每次发送其他请求时,在请求头中携带本地的 token,服务器端 token验证中间件拦截请求,对 token进行解密,得到用户信息并与数据库比对,信息存在则放行(身份验证成功)。

4.2 效果预览

node脚手架搭建服务器实现token验证的方法

4.3 开始实现

写简洁静态页面,且实现ajax 请求

login.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="../javascripts/jquery.min.js"></script>
  <title>Document</title>
</head>

<body>
  <form id="loginform">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="登录">
  </form>
  <script>
    $(function() {
      $('#loginform').on('submit', function() {
        const formdata = $(this).serialize()
        $.ajax({
          url: '/users/loginjwt',
          type: 'post',
          data: formdata,
          success(res) {
            if (res.status === 200) {
              window.sessionStorage.setItem('token', res.token);
              location.href = '/user/index.html'
            }
          }
        })
        return false
      })
    })
  </script>
</body>
</html>

index.html

<script>
  if (!sessionStorage.getItem('token')) {
    location.href = '/user/login.html'
  }
</script>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="../javascripts/jquery.min.js"></script>
  <title>Document</title>
</head>

<body>
  <h1>welcome index</h1>
  <a href="javascript:;" rel="external nofollow" >退出登录</a>
  <script>
    $(function() {
      $.ajaxSetup({
        // 发送请求前触发
        beforeSend(xhr) {
          // 在此设置自定义请求头
          xhr.setRequestHeader('authorization', sessionStorage.getItem('token'))
        }
      })
      $.ajax({
        url: '/users',
        success(res) {
          console.log(res);
        }
      })
      $('a').on('click', function() {
        sessionStorage.clear();
        location.href = '/user/login.html'
      })
    })
  </script>
</body>
</html>

4.4 注意点

值得注意的是,对于 本地 token 的验证(是否存在)一定要写在页面最顶端(防止页面加载,再次发送用户列表请求)
对于 ajax请求头,一个一个加真的很烦,此处用 $ajaxSetup方法,修改ajax 的默认配置 。配置过后,写在其下边的 ajax 请求,都会带上请求头。

到此这篇关于node脚手架搭建服务器实现token验证的方法的文章就介绍到这了,更多相关node token验证 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
无语,javascript居然支持中文(unicode)编程!
Apr 12 Javascript
javascript 学习笔记(一)DOM基本操作
Apr 08 Javascript
jquery win 7透明弹出层效果的简单代码
Aug 06 Javascript
JS命名空间的另一种实现
Aug 09 Javascript
js判断客户端是iOS还是Android等移动终端的方法
Dec 11 Javascript
javascript模拟枚举的简单实例
Mar 06 Javascript
jquery ajax局部加载方法详解(实现代码)
May 12 Javascript
Vue2.0实现1.0的搜索过滤器功能实例代码
Mar 20 Javascript
vue组件中使用iframe元素的示例代码
Dec 13 Javascript
利用jQuery+localStorage实现一个简易的计时器示例代码
Dec 25 jQuery
基于jquery实现九宫格拼图小游戏
Nov 30 jQuery
原生js实现自定义难度的扫雷游戏
Jan 22 Javascript
Vue实现图书管理案例
Jan 20 #Vue.js
浅析JavaScript中的事件委托机制跟深浅拷贝
Jan 20 #Javascript
详解vue之自行实现派发与广播(dispatch与broadcast)
Jan 19 #Vue.js
js实现电灯开关效果
Jan 19 #Javascript
jquery实现穿梭框功能
Jan 19 #jQuery
jQuery实现穿梭框效果
Jan 19 #jQuery
element el-table表格的二次封装实现(附表格高度自适应)
Jan 19 #Javascript
You might like
php array_flip() 删除数组重复元素
2009/01/14 PHP
php文字水印和php图片水印实现代码(二种加水印方法)
2013/12/25 PHP
PHP使用curl_multi实现并发请求的方法示例
2018/04/29 PHP
实用javaScript技术-屏蔽类
2006/08/15 Javascript
Jquery中ajax方法data参数的用法小结
2014/02/12 Javascript
JS延时器提示框的应用实例代码解析
2016/04/27 Javascript
整理JavaScript对DOM中各种类型的元素的常用操作
2016/05/05 Javascript
javascript鼠标滑过显示二级菜单特效
2020/11/18 Javascript
js仿腾讯QQ的web登陆界面
2016/08/19 Javascript
JS实现汉字与Unicode码相互转换的方法详解
2017/04/28 Javascript
基于JS对象创建常用方式及原理分析
2017/06/28 Javascript
JS 学习总结之正则表达式的懒惰性和贪婪性
2017/07/03 Javascript
详解React中setState回调函数
2018/06/14 Javascript
vue+element 模态框表格形式的可编辑表单实现
2019/06/07 Javascript
微信小程序实现下拉刷新动画
2019/06/21 Javascript
javascript实现自由编辑图片代码详解
2019/06/21 Javascript
[01:44]剑指西雅图 展望TI之CIS战队专访
2014/06/25 DOTA
可用于监控 mysql Master Slave 状态的python代码
2013/02/10 Python
Centos5.x下升级python到python2.7版本教程
2015/02/14 Python
python使用pil生成图片验证码的方法
2015/05/08 Python
Python处理文本文件中控制字符的方法
2017/02/07 Python
Django模板导入母版继承和自定义返回Html片段过程解析
2019/09/18 Python
python socket 聊天室实例代码详解
2019/11/14 Python
python 读取更新中的log 或其它文本方式
2019/12/24 Python
Python连接Hadoop数据中遇到的各种坑(汇总)
2020/04/14 Python
五分钟学会怎么用Pygame做一个简单的贪吃蛇
2021/01/06 Python
美国糖果店:Sugarfina
2019/02/21 全球购物
库存图片、照片、矢量图、视频和音乐:Shutterstock
2021/02/12 全球购物
六道php面试题附答案
2014/06/05 面试题
酒店员工培训方案
2014/06/02 职场文书
护理工作个人总结
2015/03/03 职场文书
结婚主持人致辞
2015/07/28 职场文书
怎样做好公众演讲能力?
2019/08/28 职场文书
win10下go mod配置方式
2021/04/25 Golang
在pycharm中无法import所安装的库解决方案
2021/05/31 Python
Python线程池与GIL全局锁实现抽奖小案例
2022/04/13 Python