node后端-JWT认证
routes/auth.js
// src/routes/auth.js
import { Router } from 'express';
const router = Router();
import User from '../models/User.js';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { JWT_SECRET } from '../config/config.js';// 注册
router.post('/register', async (req, res) => {try {const { username, password,role } = req.body;const hashedPassword = await bcrypt.hash(password, 10);const response = await User.createUser(username, hashedPassword,role);if(typeof response === 'number'){res.status(201).json({ code:201,message: '注册成功!' });}else{res.status(500).json({ code:500,message: '用户名已存在!' });} } catch (error) {res.status(500).json({ code:500, message:"注册失败" });}
});// 登录 生成JWT令牌 Token
router.post('/login', async (req, res) => {try {const { username, password } = req.body; // 1.在数据库中查找是否存在这个账号const user = await User.findByUsername(username); // 2.控制台展示错误信息if (!user) {// 明确告知前端用户不存在return res.status(401).json({ error: '用户不存在' });}const isMatch = await bcrypt.compare(password, user.password);if (!isMatch) {// 明确告知前端密码错误return res.status(401).json({ error: '密码错误' });}// 3.生成JWT Token中包含用户的id和用户的角色字段const token = jwt.sign({ id: user.id,role:user.role }, JWT_SECRET, { expiresIn: '7d' });// 4.返回Token给前端res.json({ token,userinfo:{id:user.id,username:user.username,role:user.role,avatar:user.avatarUrl} });} catch (error) {res.status(500).json({ error: '登录失败' });}
});export default router;
前端发送请求的代码:
import axios from 'axios';
// import { ElMessage } from 'element-plus';
import {BASE_URL} from "../config.js"
import {useAllDataStore} from '@/stores/index'const API_URL = `${BASE_URL}/api/auth`;
const store=useAllDataStore();
export const register = async (userData) => {const response = await axios.post(`${API_URL}/register`, userData);return response.data;
};
// 登录 测试的接口是http://localhost:3000/api/auth/login
// 导出一个名为login的异步函数,接收一个参数credentials
export const login = async (credentials) => {// 使用axios发送post请求,请求地址为API_URL/login,请求参数为credentialsconst response = await axios.post(`${API_URL}/login`, credentials);console.log(response.data);localStorage.setItem('token', response.data.token);// store.updateMenuList(generateMenuByRole(response.data.userinfo.role));store.state.token=response.data.token;store.state.avatar=response.data.userinfo.avatar;return response.data;
};
// 获取用户信息
export const getCurrentUser = () => {const token = localStorage.getItem('token');return token ? JSON.parse(atob(token.split('.')[1])) : null;
};
模块函数:
// src/models/User.js
import pool from '../config/db.js';
class User {// 创建用户(只需要用户名和密码)static async createUser(username, password,role) {try{console.log('数据库连接状态检查...');const [rows] = await pool.execute('INSERT INTO users (username, password,role) VALUES (?, ?, ?)',[username, password,role]);console.log('数据库操作成功:', rows.insertId);return rows.insertId;}catch(error){console.error('数据库操作失败:', error);return error;}}// 通过用户名查找用户static async findByUsername(username) {const [rows] = await pool.execute('SELECT * FROM users WHERE username = ?', [username]);return rows[0];}
}export default User;
server.js记得加:
app.use('/api/auth',authRoutes);