【问题标题】:NextJS screen flicker on authentication check using localstorageNextJS 使用 localstorage 进行身份验证检查时屏幕闪烁
【发布时间】:2021-02-06 02:01:28
【问题描述】:

我正在从一个后端验证我的 NextJS 前端,该后端在成功的电子邮件/密码登录 (Laravel Sanctum) 上给我一个accessToken。从那里我将该 accessToken 保存在本地存储中。

如果我有一个需要保护的页面,例如/profile,我需要在显示该页面之前验证令牌是否有效。如果无效,则需要将它们重定向到/signin 页面。所以我有以下代码可以做到这一点。

import { useRouter } from 'next/router';
import { useEffect } from 'react';

export default function Profile() {
    const router = useRouter();

    useEffect(async () => {
        const token = localStorage.getItem('accessToken');

        const resp = await fetch('https://theapiuri/api/user', {
            method: 'GET',
            headers: {
                'Authorization': 'Bearer ' + token
            }
        });

        const json = await resp.json();

        if (!token && json.status !== 200) {
            router.push('/signin');
        }
    })

    return (
        <div>
            <h1>Protected Profile Page</h1>
        </div>
    )
}

它确实有效。如果我已注销,并尝试访问/profile,它会在个人资料页面上闪烁一秒钟左右,然后重定向到登录。

这看起来一点都不好。我想知道是否有人在相同的情况下可以分享他们的解决方案,或者是否有人有一些建议将不胜感激。

【问题讨论】:

    标签: javascript reactjs next.js


    【解决方案1】:

    您的基本问题是您要立即返回个人资料页面,但令牌身份验证是异步的。在显示页面之前,您应该等待身份验证发生。有不同的方法可以做到这一点,但基本的方法是在你的状态中设置一个变量,然后根据该变量更改渲染函数返回的内容。

    例如,在这里我假设您有一些组件只显示加载器或微调器或类似的东西:

    import { useRouter } from 'next/router';
    import { useEffect, useState } from 'react';
    import LoaderComponent from 'components/Loader';
    
    export default function Profile() {
        const router = useRouter();
        const [hasAccess, setHasAccess] = useState(false);
    
        useEffect(async () => {
            const token = localStorage.getItem('accessToken');
    
            const resp = await fetch('https://theapiuri/api/user', {
                method: 'GET',
                headers: {
                    'Authorization': 'Bearer ' + token
                }
            });
    
            const json = await resp.json();
    
            if (!token && json.status !== 200) {
                router.push('/signin');
            } else {
                setHasAccess(true);
            }
        })
    
        if (!hasAccess) {
            return (
               <LoaderComponent />
            );
        }
    
        return (
            <div>
                <h1>Protected Profile Page</h1>
            </div>
        )
    }
    

    【讨论】:

      猜你喜欢
      • 2018-03-21
      • 1970-01-01
      • 2017-05-09
      • 2022-12-03
      • 2011-05-08
      • 2020-10-07
      • 1970-01-01
      • 2015-11-01
      • 1970-01-01
      相关资源
      最近更新 更多