想用 nextjs+swr+Material-UI 做个后台管理系统,请问路由守卫和用户鉴权如何做比较好呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sciel
V2EX    问与答

想用 nextjs+swr+Material-UI 做个后台管理系统,请问路由守卫和用户鉴权如何做比较好呢?

  •  
  •   sciel 2022-01-03 11:04:33 +08:00 3626 次点击
    这是一个创建于 1432 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大家好,我想用 nextJs 做个后台管理系统。但路由守卫和用户鉴权这里没太搞好,特别是在 Layout 组件里面(渲染用户可访问的菜单)。

    现在我是这样做的

    登录

    用户登录后将用户的信息保存到 localStrorage 里面,其中保存了用户的基本信息,token ,及用户的可访问 menus 。然后跳转到主页

    localStorage.setItem(KeyUser, JSON.stringify(data)) toast.success('success', { autoClose: successTime, onClose: () => { Router.push('/') } }) 

    _app.js

    _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> } 

    Layout.js

    问题主要在这里,如果直接将 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

    这是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 没多久,请多指教呀 ^_^。

    6 条回复    2022-01-03 18:29:11 +08:00
    adjusted
        1
    adjusted  
       2022-01-03 11:30:32 +08:00
    sciel
        2
    sciel  
    OP
       2022-01-03 11:37:56 +08:00
    @adjusted 没有,一会去看看哈,谢谢。
    walpurgis
        3
    walpurgis  
       2022-01-03 13:10:56 +08:00 via iPhone
    服务端渲染的页面建议把用户登录态放到 cookie 里
    jielong
        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
    sciel
        5
    sciel  
    OP
       2022-01-03 13:57:54 +08:00
    @walpurgis
    @jielong 之前试过服务端渲染,但后台给自己用的没必要,所以还是放客户端好做点。方便在 localStorage 里面取数据。 试过放 cookie 里,但 cookie 里面存的信息有限,用户 menus 放不下。
    page470075640
        6
    page470075640  
       2022-01-03 18:29:11 +08:00 via iPhone
    我的做法是登入后的页面会去拉取用户信息 如果拿不到就重定向 login 页面
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2512 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 15:13 PVG 23:13 LAX 07:13 JFK 10:13
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86