| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- const express = require('express');
- const bcrypt = require('bcryptjs');
- const jwt = require('jsonwebtoken');
- const router = express.Router();
- const authMiddleware = require('../middleware/authMiddleware');
- const User = require('../models/User');
- const Logs = require('../libs/logs');
- // 注册
- router.post('/register', async (req, res) => {
- const { username, password } = req.body;
- User.findOne({ username })
- .then(existing => {
- if (existing) {
- return Promise.reject(new Error('USER_EXISTS'));
- }
- return bcrypt.hash(password, 10);
- })
- .then(hashedPassword => {
- const user = new User({ username, password: hashedPassword });
- return user.save();
- })
- .then(() => {
- res.sendSuccess('注册成功');
- })
- .catch(err => {
- Logs.errDev('注册失败:', err);
- if (err.message === 'USER_EXISTS') {
- return res.badRequest('用户已存在');
- }
- res.badRequest(err.message);
- });
- });
- // 登录 - 支持原路径 /login 和 mock 服务路径 /login
- router.post('/login', async (req, res) => {
- const { username, password } = req.body;
- User.findOne({ username })
- .then(user => {
- if (!user) {
- return Promise.reject(new Error('USER_NOT_FOUND'));
- }
- return Promise.all([
- bcrypt.compare(password, user.password),
- Promise.resolve(user),
- ]);
- })
- .then(([isMatch, user]) => {
- if (!isMatch) {
- return Promise.reject(new Error('PASSWORD_ERROR'));
- }
- return user;
- })
- .then(user => {
- // 签发 Access Token 和 Refresh Token
- const accessToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '30m' });
- const refreshToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' });
- // 设置 refresh token 到 cookie
- res.cookie('jwt', refreshToken, {
- httpOnly: true,
- secure: true,
- sameSite: 'none',
- maxAge: 7 * 24 * 60 * 60 * 1000 // 7天
- });
- // 返回格式与前端期望一致
- res.sendSuccess({
- accessToken: accessToken,
- uid: user._id.toString(),
- username: user.username,
- roles: user.roles ?? ['user'],
- });
- })
- .catch(err => {
- Logs.errDev('登录失败:', err);
- if (err.message === 'USER_NOT_FOUND') {
- return res.badRequest('用户不存在');
- }
- if (err.message === 'PASSWORD_ERROR') {
- return res.badRequest('密码错误');
- }
- res.badRequest(err.message);
- });
- });
- // 刷新 Token - 支持 Vben Admin 的 /refresh 路径
- router.post('/refresh', async (req, res) => {
- const refreshToken = req.cookies.jwt;
- if (!refreshToken) {
- return res.unauthorized('无效的刷新token');
- }
- const decoded = jwt.verify(refreshToken, process.env.JWT_SECRET);
- User.findById(decoded.userId)
- .then(user => {
- if (!user) {
- return Promise.reject(new Error('USER_NOT_FOUND'));
- }
- // 签发新的 Access Token
- const newAccessToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '30m' });
- // 按照Vben Admin期望的格式返回
- res.send(newAccessToken);
- })
- .catch(err => {
- Logs.errDev('刷新Token失败:', err);
- res.clearCookie('jwt');
- if (err.message === 'USER_NOT_FOUND') {
- return res.unauthorized('用户不存在');
- }
- res.unauthorized(err.message);
- });
- });
- // 用户信息 - 支持 mock 服务的 /info 路径
- router.get('/info', authMiddleware, async (req, res) => {
- User.findById(req.userId).select('-password')
- .then(user => {
- if (!user) {
- return Promise.reject(new Error('USER_NOT_FOUND'));
- }
- const userInfo = {
- uid: user._id.toString(),
- username: user.username,
- roles: user.roles ?? ['user'],
- };
- res.sendSuccess(userInfo);
- })
- .catch(err => {
- Logs.errDev('获取用户信息错误:', err);
- if (err.message === 'USER_NOT_FOUND') {
- return res.notFound('用户不存在');
- }
- res.serverError(err.message);
- });
- });
- // 权限码 - 支持 mock 服务的 /codes 路径
- router.get('/codes', authMiddleware, async (req, res) => {
- try {
- // 返回所有功能的权限码
- const codes = [
- 'dashboard',
- 'dashboard:analysis',
- 'dashboard:workbench',
- 'system',
- 'system:account',
- 'system:account:settings',
- 'system:role',
- 'system:menu',
- 'system:dept',
- ];
- res.sendSuccess(codes);
- }
- catch (err) {
- Logs.errDev('获取权限码错误:', err);
- res.serverError(err.message);
- }
- });
- module.exports = router;
|