首页 > 解决方案 > 如何实现受保护的客户端路由?

问题描述

嘿!:)

我正在使用Next.js构建一个包含教师、学生和管理员仪表板的大学仪表板。

我创建了一个通用主页,您可以从中选择登录/注册。由于我们有 3 种不同类型的客户端,因此我们有多个用于身份验证的动态路由

我想要的是 ?

如果客户端未经过身份验证,我希望实际的仪表板路由得到很好的保护,即如果他/她没有登录,客户端不应该能够访问任何这些路由。

此外,如果他们确实尝试做同样的事情,他们应该被重定向到主页,在那里他们可以选择以教师、学生或管理员的身份进一步登录/注册。

问题是什么?

我有一个user object如果没有用户登录,则为空),我使用它检查一个人是否经过身份验证。因此,在我的自定义 _app中,我正在检查相同的内容,但是当用户未登录时,我只能将其重定向到特定路线,例如 Home '/',这意味着如果一个人选择以学生身份登录,他/她将再次被重定向到不应发生的主页,而是应该可以访问所有与身份验证相关的路由。

import React from 'react';
import Home from './index';
import Head from 'next/head';
import Layout from "../Components/Authentication/Layout";
import Layout2 from '../Components/SD_Comps/Layout';
import Layout3 from '../Components/EP_Comps/Layout';
import { useUser } from '../lib/hooks';
import { useRouter } from 'next/router';
import '../style.scss';
import '../node_modules/hover.css/css/hover-min.css';

export default function MyApp({ Component, pageProps }) {
  const router = useRouter();
  const [user] = useUser();

  return (
    <>
      <Head>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"></link>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
        <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"></link>
        <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"></link>
      </Head>

      {user ? (router.pathname.startsWith('/StudentDash') ? <Layout2><Component {...pageProps} /></Layout2> :
        (router.pathname.startsWith('/ExamPortal/') ? <Layout3><Component {...pageProps} /></Layout3> :
          <Layout><Component {...pageProps} /></Layout>)) : <Layout><Home /> </Layout>}

    </>
  )
}

大问题!

当用户未经过身份验证时,如何使特定路线可访问,同时保护其他路线?

标签: javascriptnode.jsreactjsroutesnext.js

解决方案


在您当前的实现中,您将所有组件发送到客户端,并根据user对象决定显示哪个组件。如果有人user手动编辑了对象,那么他们就有可能获得对未经授权的路线的访问权。

唯一安全的方法是在服务器级别对用户进行身份验证,并始终确保服务器拥有身份验证逻辑,而不是客户端。我建议您为每种类型的用户实现单独的页面:/student.js/teacher.js/admin.js根据登录结果将用户重定向到适当的页面。然后,在服务器上测试用户是否有权查看特定路由。这可以在 中完成getServerSideProps(),例如:

/pages/student.js

export default function Student({ redirect }) {
  if (redirect) {
    return null;
  }

  return (
    <>
      <!-- render your page -->
    </>
  );
}

export async function getServerSideProps({ req, res }) {
  /* Check the user status depending on your auth strategy */
  const user = req.session.get('user');

  /* Redirect to home route if user is not authenticated, or is not a 'student' type */
  if (!user || user.type !== 'student') {
    res.setHeader('Location', '/');
    res.statusCode = 302;
    return { props: { redirect: true } };
  }

  /* Proceed if authentication is successful */
  return { props: { } };
}

推荐阅读