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 相关文章推荐
img的onload的另类用法
Jan 10 Javascript
event对象获取方法总结在google浏览器下测试
Nov 03 Javascript
js中关于一个分号的崩溃示例
Nov 11 Javascript
JavaScript实现查找字符串中第一个不重复的字符
Dec 29 Javascript
JavaScript中的fontsize()方法使用详解
Jun 08 Javascript
JQUERY实现网页右下角固定位置展开关闭特效的方法
Jul 27 Javascript
JS提示:Uncaught SyntaxError:Unexpected token ) 错误的解决方法
Aug 19 Javascript
js实现的在线调色板功能完整实例
Dec 21 Javascript
angularjs封装$http为factory的方法
May 18 Javascript
react-native组件中NavigatorIOS和ListView结合使用的方法
Sep 30 Javascript
JavaScript设计模式之观察者模式实例详解
Jan 16 Javascript
详解Vue路由自动注入实践
Apr 17 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
用缓存实现静态页面的测试
2006/12/06 PHP
smarty高级特性之对象的使用方法
2015/12/25 PHP
php图片上传类 附调用方法
2016/05/15 PHP
PHP函数引用返回的实例详解
2016/09/11 PHP
Laravel框架之解决前端显示图片问题
2019/10/24 PHP
Gambit vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
js利用Array.splice实现Array的insert/remove
2009/01/13 Javascript
js 未结束的字符串常量错误解决方法
2010/06/13 Javascript
仅img元素创建后不添加到文档中会执行onload事件的解决方法
2011/07/31 Javascript
jquery cookie的用法总结
2013/11/18 Javascript
javascript背景时钟实现方法
2015/06/18 Javascript
JSON+Jquery省市区三级联动
2016/01/13 Javascript
JS实现上下左右对称的九九乘法表
2016/02/22 Javascript
JavaScript弹出对话框的三种方式
2016/03/23 Javascript
JS实现星星评分功能实例代码(两种方法)
2016/06/09 Javascript
canvas简单快速的实现知乎登录页背景效果
2017/05/08 Javascript
jQuery实现动态添加节点与遍历节点功能示例
2017/11/09 jQuery
webpack4与babel配合使es6代码可运行于低版本浏览器的方法
2018/10/12 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
2019/01/18 jQuery
详解如何使用router-link对象方式传递参数?
2019/05/02 Javascript
如何使用CSS3+JQuery实现悬浮墙式菜单
2019/06/18 jQuery
Typescript的三种运行方式(小结)
2019/09/18 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 KG VS OG
2018/03/30 DOTA
Python显示进度条的方法
2014/09/20 Python
Python代码调试的几种方法总结
2015/04/15 Python
Python的爬虫框架scrapy用21行代码写一个爬虫
2017/04/24 Python
python PyTorch预训练示例
2018/02/11 Python
Python 操作 MySQL数据库
2020/09/18 Python
2014年国培研修感言
2014/03/09 职场文书
巾帼标兵事迹材料
2014/12/26 职场文书
维稳工作承诺书
2015/01/20 职场文书
迟到检讨书范文
2015/01/27 职场文书
鼋头渚导游词
2015/02/05 职场文书
二审答辩状范文
2015/05/22 职场文书
导游词之西江千户苗寨
2019/12/24 职场文书
jquery插件实现代码雨特效
2021/04/24 jQuery