Skip to content

Commit

Permalink
🐷feat:后端登录接口拆分/前端相应调整
Browse files Browse the repository at this point in the history
  • Loading branch information
durunsong committed Oct 9, 2024
1 parent a845120 commit 50e57e3
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 54 deletions.
4 changes: 2 additions & 2 deletions server/config/db.js → server/config/db-connection.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// 配置模块
// 配置模块 单链接
const mysql = require("mysql2");

const connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "test",
multipleStatements: true
multipleStatements: true,
});

const connectDb = () => {
Expand Down
76 changes: 49 additions & 27 deletions server/controllers/userController.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const moment = require("moment");
const { connection } = require("../config/db.js");
const { connection } = require("../config/db-connection.js");

const saltRounds = 10;

Expand Down Expand Up @@ -328,64 +328,85 @@ const restoreUserApi = (req, res) => {
});
};

// 用户登录接口
// 登录接口
const loginUser = (req, res) => {
const { userName, password } = req.body;

if (!userName || !password) {
return res.status(400).json({ message: "账号和密码都是必需的" });
}

const findUserQuery =
"SELECT * FROM users WHERE userName = ? AND is_delete = 0";
connection.query(findUserQuery, [userName], async (err, results) => {
if (err) {
console.error(err);
return res.status(500).json({ message: "查询用户失败" });
}

if (results.length === 0) {
return res.status(404).json({ message: "用户不存在" });
}

const user = results[0];
const hashFromDb = user.password;

// 验证密码 检查密码是否匹配
const passWordMatch = await bcrypt.compare(password, hashFromDb);

if (!passWordMatch) {
return res.status(401).json({ message: "用户名或密码错误" });
}

// 生成 JWT
const token = jwt.sign(
{ userId: user.id, userName: user.userName },
{ id: user.id, userName: user.userName },
"jwt_secret",
{ expiresIn: "1h" },
);

// 登录时间
const login_time = moment().format("YYYY-MM-DD HH:mm:ss");

// 返回用户信息
const userInfo = {
userName: user.userName,
account: user.account,
avatar: user.avatar,
description: user.description,
create_time: user.create_time,
update_time: user.update_time,
is_delete: user.is_delete,
nick_name: user.nick_name,
role_ids: user.role_ids,
login_time: login_time,
};

res.status(200).json({ message: "登录成功", status: 200, token, userInfo });
res
.status(200)
.json({ message: "登录成功", status: 200, token, login_time });
});
};

// 获取用户详情接口
const getUserDetails = (req, res) => {
const token = req.headers.authorization?.split(" ")[1]; // 从请求头获取 token
if (!token) {
return res.status(401).json({ message: "Token 不存在" });
}
try {
const decoded = jwt.verify(token, "jwt_secret"); // 解码 JWT
const userId = decoded.id; // 获取解码后的 id
// 使用 id 查询用户详情
const findUserQuery = "SELECT * FROM users WHERE id = ? AND is_delete = 0";
connection.query(findUserQuery, [userId], (err, results) => {
if (err) {
console.error(err);
return res.status(500).json({ message: "查询用户失败" });
}
if (results.length === 0) {
return res.status(404).json({ message: "用户不存在" });
}
const user = results[0];
// 返回用户信息
const userInfo = {
id: user.id,
userName: user.userName,
account: user.account,
avatar: user.avatar,
description: user.description,
create_time: user.create_time,
update_time: user.update_time,
is_delete: user.is_delete,
nick_name: user.nick_name,
role_ids: user.role_ids,
};
res
.status(200)
.json({ message: "获取用户信息成功", status: 200, userInfo });
});
} catch {
return res.status(403).json({ message: "无效的 token" });
}
};

// 刷新jwt接口
const refreshToken = (req, res) => {
const { refreshToken } = req.body;
Expand Down Expand Up @@ -491,6 +512,7 @@ module.exports = {
permanentDeleteUser,
restoreUserApi,
loginUser,
getUserDetails,
refreshToken,
registerUser,
};
2 changes: 1 addition & 1 deletion server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const express = require("express");
const bodyParserMiddleware = require("./middleware/bodyParserMiddleware");
const corsMiddleware = require("./middleware/corsMiddleware");
const userRoutes = require("./routes/userRoutes");
const { connectDb } = require("./config/db");
const { connectDb } = require("./config/db-connection");
// const { hashExistingPasswords } = require("./controllers/userController");

// 创建服务器对象
Expand Down
3 changes: 3 additions & 0 deletions server/routes/userRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ router.post("/register", userController.registerUser);
// 刷新jwt
router.post("/refresh-token", userController.refreshToken);

// 获取用户信息
router.get("/userInfo", userController.getUserDetails);

module.exports = router;
1 change: 1 addition & 0 deletions src/i18n/package/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ const en = {
multiLevelRouteManagement: "Multi-level route management",
clickHereToMultiRouteExample:
"Click here to go to the multi-level route management example page",
login_success: "Login success",
};

export default en;
1 change: 1 addition & 0 deletions src/i18n/package/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ const zh = {
clickHereToHookExample: "点击这里跳转到案例页面",
multiLevelRouteManagement: "多级路由管理",
clickHereToMultiRouteExample: "点击这里跳转到多级路由管理案例页面",
login_success: "登录成功",
};

export default zh;
4 changes: 4 additions & 0 deletions src/service/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ export const registerApi = (params: RegisterRequestData) =>
method: "post",
data: params,
});

// userInfo
export const userInfoApi = () =>
request({ url: "/api/users/userInfo", method: "GET" });
39 changes: 21 additions & 18 deletions src/utils/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import axios, {
} from "axios";
import { ElNotification, ElLoading } from "element-plus";
import i18n from "@/i18n";
import CACHE_KEY from "@/constants/cache-key";
import { getToken, setToken } from "@/utils/cache/cookies";
// import CACHE_KEY from "@/constants/cache-key";
import { getToken } from "@/utils/cache/cookies";
import { useUserStoreHook } from "@/store/modules/user";

/** 退出登录并强制刷新页面(会重定向到登录页) */
const logout = () => {
useUserStoreHook().logout();
location.reload();
// location.reload();
};

const { t } = i18n.global;
Expand Down Expand Up @@ -66,7 +66,9 @@ const hideLoading = () => {
// 生成请求 key
const generateRequestKey = (config: InternalAxiosRequestConfig) => {
const { method, url, params, data } = config;
return `${method}:${url}:${JSON.stringify(params)}:${JSON.stringify(data)}`;
// 使用时间戳确保每次请求 key 唯一
const timestamp = Date.now();
return `${method}:${url}:${JSON.stringify(params)}:${JSON.stringify(data)}:${timestamp}`;
};

// 添加请求到 pending 中
Expand Down Expand Up @@ -143,28 +145,29 @@ request.interceptors.response.use(
},
async (error: any) => {
hideLoading();

let errorInfo = "";
const status = error.response ? error.response.status : 0;
const originalRequest = error.config;
// const originalRequest = error.config;

// 处理 HTTP 错误状态码
switch (status) {
// Token 过期时,尝试刷新 Token
case 401: {
errorInfo = t("case_401");
const refreshToken = setToken(CACHE_KEY.REFRESH_TOKEN);
if (refreshToken && !originalRequest._retry) {
originalRequest._retry = true;
// 实现刷新 token 的逻辑
// const newToken = await refreshAccessToken(refreshToken);
// setToken(newToken);
// originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
// return request(originalRequest); // 重新发起请求
} else {
// 退出登录
logout();
}
// const refreshToken = setToken(CACHE_KEY.REFRESH_TOKEN);
// if (refreshToken && !originalRequest._retry) {
// originalRequest._retry = true;
// // 实现刷新 token 的逻辑
// const newToken = await refreshAccessToken(refreshToken);
// setToken(newToken);
// originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
// return request(originalRequest); // 重新发起请求
// } else {
// // 退出登录
// logout();
// }
// 退出登录
logout();
break;
}
case 403: {
Expand Down
19 changes: 13 additions & 6 deletions src/views/login/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
import { setToken } from "@/utils/cache/cookies";
import ThemeSwitch from "@/components/ThemeSwitch/index.vue";
import { ref, reactive } from "vue";
import { loginApi, registerApi } from "@/service/login";
import { loginApi, registerApi, userInfoApi } from "@/service/login";
import { useRouter } from "vue-router";
import { ElNotification } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
Expand Down Expand Up @@ -258,18 +258,14 @@ const handleSlideSuccess = () => {
// 登录接口请求验证
const handlerExecutiveLogging = () => {
// 执行登录操作
// loading.value = true;
loading.value = true;
const params = form;
// 登录问候语
const { showGreetingNotification } = useGreeting(t);
loginApi(params)
.then((res: any) => {
if (res.status === 200) {
// 显示问候语
showGreetingNotification(res.message, res.userInfo.userName);
setToken(res.token);
setLocalData(CACHE_KEY.USER_INFO, res.userInfo);
router.push("/");
} else if (res.status === 403) {
ElNotification({
message: res.message,
Expand All @@ -283,9 +279,20 @@ const handlerExecutiveLogging = () => {
}
loading.value = false;
})
.then(() => {
userInfoApi().then((rest: any) => {
setLocalData(CACHE_KEY.USER_INFO, rest.userInfo);
// 显示问候语
showGreetingNotification(t("login_success"), rest.userInfo.userName);
router.push("/");
});
})
.catch((error: Error) => {
console.log("error", error);
loading.value = false;
})
.finally(() => {
loading.value = false;
});
};
Expand Down

0 comments on commit 50e57e3

Please sign in to comment.