React结合JSON Server实现免登录看首页、登录获全权限方案问询
实现React+JSON Server的登录权限控制(游客/登录用户区分操作)
需求说明
- 游客模式:无需登录即可进入首页查看posts,但无法执行添加、编辑、删除操作
- 登录模式:用户登录后返回首页,拥有全部操作权限
- 技术栈:React + JSON Server
解决方案步骤
1. 完善登录状态持久化逻辑
修改现有登录函数,在验证成功后将登录状态存入localStorage,确保页面刷新后状态不丢失:
const ProceedLogin = (e) => { e.preventDefault() if (validation()) { const axiosFunction = async () => { try { const axiosRes = await axios.get(`http://localhost:3000/user/${username}`) const data = axiosRes.data if (Object.keys(data).length === 0) { toast.error("请输入有效的用户名") } else if (data.password === password) { toast.success("登录成功") // 存储登录状态与用户信息到本地存储 localStorage.setItem('isLoggedIn', 'true') localStorage.setItem('currentUser', JSON.stringify(data)) navigate("/") } else { toast.error("密码错误") } } catch (err) { console.log(err); toast.error("用户不存在") } } axiosFunction() } }
2. 首页权限控制实现
在首页组件中读取登录状态,根据状态控制操作按钮的显示与功能可用性:
import { useState, useEffect } from 'react'; import axios from 'axios'; import { toast } from 'react-toastify'; const Home = () => { const [posts, setPosts] = useState([]); const [isLoggedIn, setIsLoggedIn] = useState(false); // 页面加载时初始化登录状态并拉取帖子 useEffect(() => { const loggedIn = localStorage.getItem('isLoggedIn') === 'true'; setIsLoggedIn(loggedIn); fetchPosts(); }, []); // 获取帖子列表(游客与登录用户均可访问) const fetchPosts = async () => { try { const res = await axios.get('http://localhost:3000/posts'); setPosts(res.data); } catch (err) { toast.error("加载帖子失败"); } }; // 添加帖子(仅登录用户可执行) const handleAddPost = async (newPost) => { if (!isLoggedIn) { toast.error("请先登录再添加帖子"); return; } try { await axios.post('http://localhost:3000/posts', newPost); fetchPosts(); toast.success("帖子添加成功"); } catch (err) { toast.error("添加帖子失败"); } }; // 编辑帖子(仅登录用户可执行) const handleEditPost = async (postId, updatedPost) => { if (!isLoggedIn) { toast.error("请先登录再编辑帖子"); return; } try { await axios.put(`http://localhost:3000/posts/${postId}`, updatedPost); fetchPosts(); toast.success("帖子编辑成功"); } catch (err) { toast.error("编辑帖子失败"); } }; // 删除帖子(仅登录用户可执行) const handleDeletePost = async (postId) => { if (!isLoggedIn) { toast.error("请先登录再删除帖子"); return; } try { await axios.delete(`http://localhost:3000/posts/${postId}`); fetchPosts(); toast.success("帖子删除成功"); } catch (err) { toast.error("删除帖子失败"); } }; // 登出功能 const handleLogout = () => { localStorage.removeItem('isLoggedIn'); localStorage.removeItem('currentUser'); setIsLoggedIn(false); toast.success("已登出"); }; return ( <div className="home"> <h1>帖子列表</h1> {/* 登出按钮仅登录后显示 */} {isLoggedIn && <button onClick={handleLogout}>登出</button>} {/* 添加按钮仅登录后显示 */} {isLoggedIn && <button onClick={() => handleAddPost({ title: "新帖子", content: "默认内容" })}>添加帖子</button>} <div className="posts-list"> {posts.map(post => ( <div key={post.id} className="post-item"> <h3>{post.title}</h3> <p>{post.content}</p> {/* 编辑/删除按钮仅登录后显示 */} {isLoggedIn && ( <div className="post-actions"> <button onClick={() => handleEditPost(post.id, { ...post, title: `编辑:${post.title}` })}>编辑</button> <button onClick={() => handleDeletePost(post.id)}>删除</button> </div> )} </div> ))} </div> </div> ); }; export default Home;
3. 补充说明
- 小型项目用
localStorage存储登录状态足够,大型项目建议改用React Context或Redux做全局状态管理 - 前端权限控制仅做界面层限制,若需要更严格的权限校验,可给JSON Server添加中间件拦截修改类请求(JSON Server本身为轻量工具,适合演示场景)
内容的提问来源于stack exchange,提问作者mohamed Allam
相关产品推荐
相关产品推荐

