大家好,我想用 nextJs 做个后台管理系统。但路由守卫和用户鉴权这里没太搞好,特别是在 Layout 组件里面(渲染用户可访问的菜单)。
现在我是这样做的
用户登录后将用户的信息保存到 localStrorage 里面,其中保存了用户的基本信息,token ,及用户的可访问 menus 。然后跳转到主页
localStorage.setItem(KeyUser, JSON.stringify(data))
toast.success('success', {
autoClose: successTime, onClose: () => {
Router.push('/')
}
})
在 _app.js
页面的基本布局这里会使用 Layout 组件进行用户可访问的菜单渲染。代码如下
import {Layout} from "../components/Layout";
function MyApp({Component, pageProps, router}) {
...
if (router.route === '/login') return <><Component {...pageProps} /></>
return <ThemeProvider theme={theme}>
<Layout dark={dark} setDark={handleSetDark} theme={theme}>
<Component {...pageProps} />
</Layout>
<ToastContainer position={'top-center'} theme={'dark'}/>
</ThemeProvider>
}
问题主要在这里,如果直接将 localStorage 的用户信息删除,由于useUser
里没有判断到用户信息为空而跳转到login
页面,所以继续向Layout
组件里面走了。
这里的前两个 if 条件也不能阻止程序往下执行所以 {menus.map
里面回报 undefined.
(其实我有在 useUser 里面做判断,如果用户信息不存在直接到/login
页面。但没有起效果)
export const Layout = ({children, dark, setDark, theme}) => {
const {menus, u, mutate, loading, token, loggedOut} = useUser()
if (loading) return <>{children}</>
if (!u) return <></>
...
return (<Box sx={{display: 'flex'}}>
<List>
{menus.map(item)=> ...}
</List>
...
{childlren}
...
</Box>);
}
这是useUser.js
用来获取用户的信息,如果用户没有登录就直接跳到登录页面。
获取用户信息是从localStorage
里面进行获取的,参照官网的 demo 中改来。
...
const userFetcher = async () => {
let u = localStorage.getItem(KeyUser)
if (isEmpty(u)) {
let error = new Error("Not authorized!");
error.status = 403
throw error
}
return JSON.parse(u)
}
export const useUser = () => {
const {data, mutate, error} = useSWR(`api_user`, userFetcher)
const loggedOut = error && error.status === 403;
const loading = loggedOut === undefined || !data && !error;
if (loggedOut) {
Router.push('/login')
}
if (data) {
const {u, menus, token} = data.data
return {loading, mutate, u, menus, token, loggedOut}
}
return {loading, loggedOut}
}
所以想请问一下大家这块如何做比较好呢?
刚学 react,nextjs 没多久,请多指教呀 ^_^。
1
adjusted 2022-01-03 11:30:32 +08:00
|
3
walpurgis 2022-01-03 13:10:56 +08:00 via iPhone
服务端渲染的页面建议把用户登录态放到 cookie 里
|
4
jielong 2022-01-03 13:31:58 +08:00
用了 next 最好能做到服务端渲染阶段拿到用户信息,不然感觉会很奇怪 😅
推荐这两个库,用户信息,token 放 cookie ,能在 serverSide 拿到 https://github.com/bjoluc/next-redux-cookie-wrapper https://github.com/kirill-konshin/next-redux-wrapper |
5
sciel OP |
6
page470075640 2022-01-03 18:29:11 +08:00 via iPhone
我的做法是登入后的页面会去拉取用户信息 如果拿不到就重定向 login 页面
|