前期工作
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是否有效登录