簡體   English   中英

防止路由器在重定向前短暫加載頁面

[英]Prevent Router from Loading Page Briefly before Redirect

我的 NextJS 應用程序有一個 session 上下文,任何訪問/app/目錄頁面的人都必須在允許用戶訪問頁面之前通過授權檢查 go。

雖然我的邏輯可以在沒有適當身份驗證的情況下重定向用戶,但它有點小故障,因為當有人導航到 URL 時, /app/profile/頁面會在被路由器重定向之前短暫加載。

我想知道在路由器加載未經授權的頁面並將它們重定向到/login/頁面之前進行此檢查的最佳方法是什么。

以下是授權檢查的步驟:

  1. 查是用戶object有屬性, authorized
  2. 向服務器查詢 session 令牌
  3. 如果來自服務器請求的 object 返回時授權 = false,則將用戶重定向到/login/

這是代碼:

import React, { createContext, useContext, useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import axios from 'axios'

export const SessionContext = createContext(null);

const AppSession = ({ children }) => {
    const router = useRouter()
    const routerPath = router.pathname;
    const [user, setUser] = useState({ user_id: '', user_email: '', user_avatar: ''})

    useEffect(()=> {
        // Check for populated user state if pages are accessed with the path /app/
        if (routerPath.includes("/app/")){
            if (user){
                if(user.authenticated === undefined){
                    // Check if user session exists
                    axios.get('/api/auth/session/')
                    .then(res => {
                        const data = res.data;
                        // Update user state depending on the data returned
                        setUser(data)
                        // If user session does not exist, redirect to /login/
                        if (data.authenticated === false){
                            router.push('/login/')
                        }
                    })
                    .catch(err => {
                        console.log(err)
                    });
                }
            }
        }
    }, [])

    return (
        <SessionContext.Provider value={{user, setUser}}>
            {children}
        </SessionContext.Provider>
    )

}

export const getUserState = () => {
    const { user } = useContext(SessionContext)
    return user;
}

export const updateUserState = () => {
    const { setUser } = useContext(SessionContext)
    return (user) => {
        setUser(user);
    }
}

export default AppSession;

由於user.authenticated未在初始user state 中定義,因此您可以在user.authenticated未定義時有條件地呈現null或某些加載指示器。 定義user.authenticated后,代碼應重定向到"/login"或呈現SessionContext.Provider組件。

例子:

const AppSession = ({ children }) => {
  const router = useRouter();
  const routerPath = router.pathname;
  const [user, setUser] = useState({ user_id: '', user_email: '', user_avatar: ''});

  ...

  if (user.authenticated === undefined) {
    return null; // or loading indicator/spinner/etc
  }

  return (
    <SessionContext.Provider value={{ user, setUser }}>
      {children}
    </SessionContext.Provider>
  );
};

查看getServerSideProps 、getServerSideProps 中的getServerSideProps這篇文章

在您的客戶端,如果您從頁面導出名為getServerSideProps的 NextJS function 定義,NextJS 會使用getServerSideProps返回的數據在每個請求上預呈現頁面。

換句話說,您可以在預渲染頁面時使用getServerSideProps檢索和檢查用戶,然后在不滿足您的條件時選擇重定向而不是渲染。

這是一個例子。

function Page({ data }) {
  // Render data...
}

export async function getServerSideProps(context) {
  const { req, res } = context;
  try {
    // get your user
    if (user.authenticated === undefined) {
      return {
        redirect: {
          permanent: false,
          destination: `/`,
        },
      };
    }

    
    return {
      props: {
        // any static props you want to deliver to the component
      },
    };
  } catch (e) {
    console.error("uh oh");
    return;
  }
}

祝你好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM