用express实现token鉴权

前期工作
npm init
npm install experss cors jsonwebtoken express-jwt@7 mysql

在这里插入图片描述
npm下载依赖包完成后
创建app.js

const express = require("express");
const app = express();

// 跨域
const cors = require("cors");
app.use(cors());


// 处理post请求
app.use(express.urlencoded({ extended: false }));
app.use(express.json());

const { expressjwt } = require("express-jwt");
app.use(
  expressjwt({
    secret: "liuhailang",
    // 解密算法
    algorithms: ["HS256"],
    // 除了带api的接口,其他接口都需要验证token
  }).unless({ path: [/^\/api\//] })
);

// 引用router
const router = require("./server/route/index");
app.use(router);

app.listen(3000, () => {
  console.log("Server is running at http://127.0.0.1:3000");
});

再node_modules创建通缉目录 server和web utils文件方便后续操作

创建db.js连接数据库

const mysql = require("mysql");
let connection = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "0519",
  database: "koa2", //数据库名称
});

// 测试连接
// connection.connect((err) => {
//   if (err) {
//     console.log("数据库连接失败");
//   } else {
//     console.log("数据库连接成功");
//     // 读取一条数据
//     connection.query("select * from users", (err, result) => {
//       if (err) {
//         console.log("读取数据失败");
//       } else {
//         console.log(result);
//       }
//     });
//   }
// });

module.exports = connection;

创建路由server/route/index.js

const express = require("express");
const router = express.Router();
// 连接数据库
const db = require("../utils/db");

// jwt 将用户信息加密成token
const jwt = require("jsonwebtoken");
// 密钥
const secretKey = "liuhailang";

// 登录路由
router.post("/api/login", (req, res) => {
  let userObj = req.body;
  const { username, password } = userObj;
  let account = username;
  let pwd = password;
  const tokenStr = jwt.sign(
    // 三个参数 1.加密的数据 2.密钥 3.过期时间
    { username: account },
    secretKey,
    { expiresIn: "1h" }
  );

  // 获取前端传来的数据,查询数据库是否存在该用户
  db.query(
    "select * from users where account=? and pwd=?",
    [account, pwd],
    (err, data) => {
      if (data.length === 0) {
        res.send({ code: 500, msg: "用户名或密码错误" });
      } else {
        // 判断token是否存在
        if (data[0].token) {
          res.send({
            code: 200,
            msg: "欢迎登录",
            token: data[0].token, //发送token给用户
          });
        } else {
          // 更新token
          db.query(
            "update users set token=? where account=?",
            [tokenStr, account],
            (err, data) => {
              if (err) {
                console.log(err);
                res.send({ code: 500, msg: "服务器错误" });
              } else {
                res.send({
                  code: 200,
                  msg: "欢迎登录",
                  token: tokenStr, //发送token给用户
                });
              }
            }
          );
        }
      }
    }
  );
});

// 注册
router.post("/api/register", (req, res) => {
  let userObj = req.body;
  const { username, password } = userObj;
  let account = username;
  let pwd = password;
  // 生成token
  const tokenStr = jwt.sign(
    // 三个参数 1.加密的数据 2.密钥 3.过期时间
    { username: account },
    secretKey,
    { expiresIn: "1h" }
  );

  let token = tokenStr;
  // 获取前端传来的数据,查询数据库是否存在该用户
  db.query(
    "insert into users(account,pwd,token) values(?,?,?)",
    [account, pwd, token],
    (err, data) => {
      if (err) {
        console.log(err);
        res.send({ code: 500, msg: "服务器错误" });
      } else {
        res.send({
          code: 200,
          msg: "注册成功",
          token: tokenStr, //发送token给用户
        });
      }
    }
  );
});

router.get("/getData", (req, res) => {
  // 获取前端传来的数据,查询数据库是否存在该用户
  db.query("select * from subject", (err, data) => {
    if (err) {
      console.log(err);
      res.send({ code: 500, msg: "服务器错误" });
    } else {
      res.send({
        code: 200,
        msg: "获取数据成功",
        data: data,
      });
    }
  });
});

module.exports = router;

接下来再web文件下创建login.html和reg.html两个文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入axios -->
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
  </head>
  <body>
    <!-- 登录注册 -->
    <div id="login">
      <input type="text" id="username" placeholder="请输入用户名" />
      <input type="password" id="password" placeholder="请输入密码" />
      <button id="btn">登录</button>
      <button id="huoqu">获取数据</button>
      <div id="list"></div>
    </div>
    <script>
      // 登录注册逻辑
      // 1.获取元素
      let username = document.getElementById("username");
      let password = document.getElementById("password");
      let btn = document.getElementById("btn");
      // 2.绑定事件
      btn.onclick = function () {
        // 3.获取用户输入的值
        let usernameValue = username.value;
        let passwordValue = password.value;
        // 4.发送请求
        axios
          .post("http://localhost:3000/api/login", {
            username: usernameValue,
            password: passwordValue,
          })
          .then(function (res) {
            console.log(res);
            // 储存token
            localStorage.setItem("token", res.data.token);
          })
          .catch(function (err) {
            console.log(err);
          });
      };

      // 获取数据
      let huoqu = document.getElementById("huoqu");
      let list = document.getElementById("list");
      huoqu.onclick = function () {
        // 2.发送请求
        axios
          .get("http://localhost:3000/getData", {
            headers: {
              Authorization: "Bearer " + localStorage.getItem("token"),
            },
          })
          .then(function (res) {
            // const { data } = res.data;
            // for (let i = 0; i < data.length; i++) {
            //   list.innerHTML += `
            //     <div>${data[i].title}</div>
            //   `;
            // }
            // 用forEach重写
            res.data.data.forEach((item) => {
              list.innerHTML += `
                <div>${item.title}</div>
              `;
            });

          
          })
          .catch(function (err) {
            console.log(err);
          });

      };

    </script>
  </body>
</html>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入axios -->
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
  </head>
  <body>
    <!-- 注册 -->
    <div id="register">
      <input type="text" id="username" placeholder="请输入用户名" />
      <input type="password" id="password" placeholder="请输入密码" />
      <button id="btn">注册</button>
    </div>

    <script>
      // 注册逻辑
      // 1.获取元素
      let username = document.getElementById("username");
      let password = document.getElementById("password");
      let btn = document.getElementById("btn");
      // 2.绑定事件
      btn.onclick = function () {
        // 3.获取用户输入的值
        let usernameValue = username.value;
        let passwordValue = password.value;
        // 4.发送请求
        axios
          .post("http://localhost:3000/api/register", {
            username: usernameValue,
            password: passwordValue,
          })
          .then(function (res) {
            console.log(res);
          })
          .catch(function (err) {
            console.log(err);
          });
      };

 

    </script>
  </body>
</html>

根据图片创建数据表的users 和subject两个文件
在这里插入图片描述
在这里插入图片描述
现在就可以模拟前后端分离token 鉴权了
在这里插入图片描述

在这里插入图片描述
后端返回的token储存再local Storage中
每次获取数据的时候必须请求头携带token判断token是否有效登录
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lionliu0519

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值