javascript - 如何实现受保护的客户端路由?
问题描述
嘿!:)
我正在使用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>}
</>
)
}
大问题!
当用户未经过身份验证时,如何使特定路线可访问,同时保护其他路线?
解决方案
在您当前的实现中,您将所有组件发送到客户端,并根据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: { } };
}
推荐阅读
- react-native - Expo MediaLibrary getAlbumsAsync doesn't get WhatsApp Folders
- cadence-workflow - Cadence 如何成为一个演员框架?
- android - Version numbers on Google Play gets consumed?
- typescript - Define a recursive array of even length in TypeScript
- javascript - 如何禁用切换按钮?
- python - Pandas lookup within groupby dataframe
- powershell - Windows 10 Powershell Automation Script Issue
- php - Gutenberg Blocks:使用 `register_block_type_from_metadata()` 注册多个块会在控制台中引发错误
- cryptography - How to derive RSA key from PGP key JavaScript?
- boost - boost Spirit x3 的编译性能问题