React结合Axios实现登录后显示用户名,现有代码返回空字符串如何解决
React+Axios登录后展示用户名问题修复方案
现有代码核心问题
- 接口调用不匹配:
/api/register是用户注册的POST接口,你前端用GET请求调用该接口,本身请求就不合法,且该接口没有查询登录用户信息的逻辑。 - 后端接口无返回:现有注册接口完成数据库写入后仅打印错误,没有给前端返回任何响应数据,无法获取到用户名字段。
- 前端请求逻辑错误:Axios请求直接写在组件顶层,会导致组件每次渲染都重复发起请求;且
console.log(showName)是同步执行代码,Axios为异步请求,请求返回前打印的是状态的初始空值。 - 缺少登录态逻辑:没有登录接口、登录态校验传递逻辑,无法识别当前登录的用户身份。
具体修改步骤
1. 后端新增/完善接口
首先安装JWT依赖用于生成登录凭证:npm i jsonwebtoken
新增登录接口
const jwt = require('jsonwebtoken') // 自定义加密密钥,生产环境请配置到环境变量避免泄露 const JWT_SECRET = 'your_custom_jwt_secret' app.post("/api/login", async(req, res) => { const { email, password } = req.body // 校验账号密码是否匹配数据库数据 connection.query( "SELECT * FROM teacherlogins WHERE email = ? AND password = ?", [email, password], (err, result) => { if(err) return res.status(500).json({ msg: '服务器异常' }) if(result.length === 0) return res.status(401).json({ msg: '账号或密码错误' }) // 生成有效期24小时的登录token const token = jwt.sign( { userId: result[0].id, username: result[0].name }, JWT_SECRET, { expiresIn: '24h' } ) // 返回用户信息和登录凭证 res.json({ code: 200, data: { username: result[0].name, token } }) } ) })
新增获取当前用户信息接口
app.get("/api/userInfo", async(req, res) => { // 从请求头获取登录token const token = req.headers.authorization?.split(' ')[1] if(!token) return res.status(401).json({ msg: '未登录' }) try { // 校验token有效性,解析用户信息 const decoded = jwt.verify(token, JWT_SECRET) res.json({ code: 200, data: { username: decoded.username } }) } catch(e) { return res.status(401).json({ msg: '登录凭证失效,请重新登录' }) } })
完善原有注册接口的返回逻辑
app.post("/api/register", async(req, res) => { const username = req.body.username const email = req.body.email const password = req.body.password connection.query( "INSERT INTO teacherlogins (name, email, password) VALUES (?,?,?)", [username, email, password], (err,result) => { if(err) return res.status(500).json({ msg: '注册失败', error: err }) res.json({ code: 200, msg: '注册成功' }) } ) })
2. 前端逻辑修改
登录页逻辑:用户提交登录后保存凭证
// 登录提交函数示例 const handleLogin = async (loginForm) => { const res = await Axios.post('http://localhost:1337/api/login', loginForm) if(res.data.code === 200) { // 保存token到本地存储 localStorage.setItem('user_token', res.data.data.token) // 可直接跳转首页,或直接保存用户名到状态 } }
展示用户名的组件逻辑
import { useState, useEffect } from 'react' import Axios from 'axios' const Header = () => { const [showName, setShowName] = useState("") // 把请求放在useEffect中,仅组件首次挂载时触发 useEffect(() => { const token = localStorage.getItem('user_token') if(!token) return // 请求携带登录token Axios.get("http://localhost:1337/api/userInfo", { headers: { Authorization: `Bearer ${token}` } }).then((response) => { if(response.data.code === 200) { setShowName(response.data.data.username) } }) }, []) return ( <div className="header-right"> {/* 登录状态判断,未登录时展示登录入口 */} { showName ? <p>{showName}</p> : <button>登录</button> } </div> ) }
注意事项
- 示例代码中密码明文存储在数据库属于不安全行为,生产环境请使用
bcrypt等加密工具对密码做哈希处理后再存储。 - 如果存在跨域问题,请在后端配置cors跨域允许。
内容的提问来源于stack exchange,提问作者Saif Khadraoui
相关产品推荐
相关产品推荐

