6

我正在尝试将身份验证与next-auth应用程序中的库集成。我一直在关注这里给出的官方教程https://github.com/nextauthjs/next-auth-example/。给定示例的问题是,我需要检查每个页面上是否存在需要像这样进行身份验证的会话。

    import { useState, useEffect } from 'react';
    import { useSession } from 'next-auth/client'
    
    export default function Page () {
      const [ session, loading ] = useSession()
      
      // Fetch content from protected route
      useEffect(()=>{
        const fetchData = async () => {
          const res = await fetch('/api/examples/protected')
          const json = await res.json()
        }
        fetchData()
      },[session])
    
      // When rendering client side don't display anything until loading is complete
      if (typeof window !== 'undefined' && loading) return null
    
      // If no session exists, display access denied message
      if (!session) { return  <Layout><AccessDenied/></Layout> }
    
      // If session exists, display content
      return (
        <Layout>
          <h1>Protected Page</h1>
          <p><strong>{content || "\u00a0"}</strong></p>
        </Layout>
      )
    }

或者像这样用于服务器端检查

    import { useSession, getSession } from 'next-auth/client'
    import Layout from '../components/layout'
    
    export default function Page () {
      // As this page uses Server Side Rendering, the `session` will be already
      // populated on render without needing to go through a loading stage.
      // This is possible because of the shared context configured in `_app.js` that
      // is used by `useSession()`.
      const [ session, loading ] = useSession()
    
      return (
        <Layout>
          <h1>Server Side Rendering</h1>
          <p>
            This page uses the universal <strong>getSession()</strong> method in <strong>getServerSideProps()</strong>.
          </p>
          <p>
            Using <strong>getSession()</strong> in <strong>getServerSideProps()</strong> is the recommended approach if you need to
            support Server Side Rendering with authentication.
          </p>
          <p>
            The advantage of Server Side Rendering is this page does not require client side JavaScript.
          </p>
          <p>
            The disadvantage of Server Side Rendering is that this page is slower to render.
          </p>
        </Layout>
      )
    }
    
    // Export the `session` prop to use sessions with Server Side Rendering
    export async function getServerSideProps(context) {
      return {
        props: {
          session: await getSession(context)
        }
      }
    }

这很让人头疼,因为我们需要在每个需要身份验证的页面上手动正确,有没有办法全局检查给定的路由是否是受保护的路由,如果没有登录则重定向,而不是在每个页面上都写这个?

4

1 回答 1

20

是的,您需要检查每个页面,并且您的逻辑没问题(显示微调器直到身份验证状态可用)但是,您可以提升身份验证状态,因此您不必auth为每个页面重复代码, _app组件是一个完美的地方这是因为它自然地包装了所有其他组件(页面)。

      <AuthProvider>
        {/* if requireAuth property is present - protect the page */}
        {Component.requireAuth ? (
          <AuthGuard>
            <Component {...pageProps} />
          </AuthGuard>
        ) : (
          // public page
          <Component {...pageProps} />
        )}
      </AuthProvider>

AuthProvider组件封装了用于设置第三方提供商(Firebase、AWS Cognito、Next-Auth)的逻辑

AuthGuard是您放置身份验证检查逻辑的组件。您会注意到它AuthGuard正在包装Component(这是 Next.js 框架中的实际页面)。所以AuthGuard会在查询 auth 提供者时显示加载指示器,如果 auth 为 true,它将显示Component如果 auth 为 false,它可能会显示登录弹出窗口或重定向到登录页面。

关于Component.requireAuth这是一个方便的属性,它在每个页面上设置以将其标记Component为需要身份验证,如果该属性为 false,AuthGuard则永远不会呈现。

我已经更详细地介绍了这种模式:Protecting static pages in Next.js application

而且我还制作了一个示例演示应用程序(来源)

于 2021-05-17T12:05:23.073 回答