尝试使用HOC和Cookie在Nextjs中实现私有(经过身份验证的)路由,但在以下时遇到错误:
TypeError: Object(...) is not a function at export default withPrivateRoute(Private);
我已经在应用程序的其他地方检查了cookie是否可用,并随请求一起发送。它们似乎可以在服务器端使用。
`/ components / withPrivateRoute中的HOC
import { withRouter } from 'next/router';
import { withCookies } from 'react-cookie';
const withPrivateRoute = (authComponent) => {
return class Private extends React.Component {
componentDidMount() {
console.log('PRIVATE ROUTE', this.props);
const { router, cookies } = this.props;
const intendedRoute = router.pathname;
const isAdmin = !!cookies.get('isAdmin');
const isAuthenticated = !!cookies.get('username');
if (!isAuthenticated) {
router.push({
pathname: '/login',
query: { from: intendedRoute },
});
}
if (
isAuthenticated &&
router.pathname.includes('admin') &&
!isAdmin
) {
router.push('/');
}
}
render() {
// eslint-disable-next-line react/jsx-props-no-spreading
return <authComponent {...this.props} />;
}
}
}
export default withCookies(withRouter(withPrivateRoute));
私人路线示例:
import withPrivateRoute from '../components/withPrivateRoute';
import getCategories from '../lib/getCategories';
const Private = (props) => {
console.log('props', props);
return <div>Private route </div>;
}
export default withPrivateRoute(Private);
export async function getStaticProps() {
let categories = await getCategories();
categories = categories.data.categories;
return {
props: {
categories,
},
};
}
答案 0 :(得分:0)
此后,我发现了一种更好的方法来处理this discussion中的Nextjs中的私有路由:
一切都在getServerSideProps
内部处理,不需要HOC。
class Private extends React.Component{
render() {
console.log('props', this.props);
return <p>Private route</p>;
}
}
export default Private;
export async function getServerSideProps(context) {
const { req: { headers, url }, res } = context;
const cookies = {};
if (headers && headers.cookie) {
headers.cookie.split(';').forEach((cookie) => {
const parts = cookie.match(/(.*?)=(.*)$/);
cookies[parts[1].trim()] = (parts[2] || '').trim();
});
}
const isAuthenticated = !!cookies.username;
const isAdmin = !!cookies.isAdmin;
if (!isAuthenticated) {
res.setHeader('Location', `/login?from=${url}`);
res.statusCode = 307;
}
if (
isAuthenticated &&
url.includes('admin') &&
!isAdmin
) {
res.setHeader('Location', '/');
res.statusCode = 307;
}
return {
props: {
},
};
}