我正在构建一个 Next.js 项目,我想在其中实现类似于react-private 路由的私有路由。在React中,这可以通过使用react-router来完成,但在Next.js中这是不能完成的。我猜 next/auth 可以选择创建私有路由,但我没有使用 next/auth。
我创建了一个 HOC 来检查用户是否已登录,但我无法将用户重定向到成功登录后他/她想要去的私人页面。如何在 Next.js 中实现此功能?有人可以帮我吗?
这是 HOC,我使用了有关私有路由的博客中的代码。
import React from 'react';
import Router from 'next/router';
const login = '/login'; // Define your login route address.
/**
* Check user authentication and authorization
* It depends on you and your auth service provider.
* @returns {{auth: null}}
*/
const checkUserAuthentication = () => {
const token = typeof window !== "undefined" && localStorage.getItem('test_token');
if(!token) {
return { auth: null };
} else return {auth:true};
// change null to { isAdmin: true } for test it.
};
export default WrappedComponent => {
const hocComponent = ({ ...props }) => <WrappedComponent {...props} />;
hocComponent.getInitialProps = async (context) => {
const userAuth = await checkUserAuthentication();
// Are you an authorized user or not?
if (!userAuth?.auth) {
// Handle server-side and client-side rendering.
if (context.res) {
context.res?.writeHead(302, {
Location: login,
});
context.res?.end();
} else {
Router.replace(login);
}
} else if (WrappedComponent.getInitialProps) {
const wrappedProps = await WrappedComponent.getInitialProps({...context, auth: userAuth});
return { ...wrappedProps, userAuth };
}
return { userAuth };
};
return hocComponent;
};
这是我的私人路线代码:
import withPrivateRoute from "../../components/withPrivateRoute";
// import WrappedComponent from "../../components/WrappedComponent";
const profilePage = () => {
return (
<div>
<h1>This is private route</h1>
</div>
)
}
export default withPrivateRoute(profilePage);
要重定向回用户尝试访问的受保护路由,您可以在重定向到登录页面时传递带有当前路径(受保护路由路径)的查询参数。
// Authentication HOC
const loginPath = `/login?from=${encodeURIComponent(context.asPath)}`;
if (context.res) {
context.res.writeHead(302, {
Location: loginPath
});
context.res.end();
} else {
Router.replace(loginPath);
}
在登录页面,登录完成后,您可以通过以下方式访问查询参数:router.query.from
并用它来将用户重定向回来。
// Login page
const login = () => {
// Your login logic
// If login is successful, redirect back to `router.query.from`
// or fallback to `/homepage` if login page was accessed directly
router.push(router.query.from && decodeURIComponent(router.query.from) ?? '/homepage');
}
注意encodeURIComponent
/decodeURIComponent
使用是因为asPath
属性可以包含查询字符串参数。这些需要在传递到登录 URL 时进行编码,然后在使用 URL 重定向回来时进行解码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)