在 Next.js 中创建一个 HOC(高阶组件)进行身份验证
Posted
技术标签:
【中文标题】在 Next.js 中创建一个 HOC(高阶组件)进行身份验证【英文标题】:Create a HOC (higher order component) for authentication in Next.js 【发布时间】:2021-05-10 20:16:13 【问题描述】:所以我在 Next.js 应用程序中创建身份验证逻辑。我创建了处理请求的/api/auth/login
页面,如果用户的数据良好,我将创建一个带有JWT 令牌的httpOnly
cookie 并将一些数据返回到前端。这部分工作正常,但我需要一些方法来保护某些页面,以便只有登录的用户才能访问它们,我在为此创建 HOC 时遇到问题。
我看到的最好的方法是使用 getInitialProps
但在 Next.js 网站上它说我不应该再使用它了,所以我考虑使用 getServerSideProps
但这也不起作用,或者我可能做错了什么。
这是我的 HOC 代码:
(cookie 存储在userToken
名称下)
import React from 'react';
const jwt = require('jsonwebtoken');
const RequireAuthentication = (WrappedComponent) =>
return WrappedComponent;
;
export async function getServerSideProps(req,res)
const token = req.cookies.userToken || null;
// no token so i take user to login page
if (!token)
res.statusCode = 302;
res.setHeader('Location', '/admin/login')
return props:
else
// we have token so i return nothing without changing location
return;
export default RequireAuthentication;
如果您对如何使用 cookie 在 Next.js 中处理身份验证有任何其他想法,我将不胜感激,因为我是服务器端渲染 react/auth 的新手。
【问题讨论】:
【参考方案1】:您应该将您的身份验证逻辑从getServerSideProps
中分离并提取到一个可重用的高阶函数中。
例如,您可以拥有以下函数,该函数将接受另一个函数(您的 getServerSideProps
),如果未设置 userToken
,则会重定向到您的登录页面。
export function requireAuthentication(gssp)
return async (context) =>
const req, res = context;
const token = req.cookies.userToken;
if (!token)
// Redirect to login page
return
redirect:
destination: '/admin/login',
statusCode: 302
;
return await gssp(context); // Continue on to call `getServerSideProps` logic
然后您可以通过包装getServerSideProps
函数在您的页面中使用它。
// pages/index.js (or some other page)
export const getServerSideProps = requireAuthentication(context =>
// Your normal `getServerSideProps` code here
)
【讨论】:
好的,我的 req.headers 中什至没有 cookie 对象,我只是开始一个新线程,因为我不确定这是否与您的答案有关,但非常感谢您的帮助! @deadcoder0904 将gssp
输入为requireAuthentication(gssp: GetServerSideProps)
对我有用。关于您遇到的错误,您可能需要为此创建一个新问题,因为我认为它与此问题无关。
@deadcoder0904 您可能想为您遇到的打字问题创建一个新问题。
@juliomalves 我会的,但这不是什么大问题。现在使用any
:)
有道理-谢谢!!【参考方案2】:
根据 Julio 的回答,我使它适用于 iron-session
:
import GetServerSidePropsContext from 'next'
import withSessionSsr from '@/utils/index'
export const withAuth = (gssp: any) =>
return async (context: GetServerSidePropsContext) =>
const req = context
const user = req.session.user
if (!user)
return
redirect:
destination: '/',
statusCode: 302,
,
return await gssp(context)
export const withAuthSsr = (handler: any) => withSessionSsr(withAuth(handler))
然后我像这样使用它:
export const getServerSideProps = withAuthSsr((context: GetServerSidePropsContext) =>
return
props: ,
)
我的withSessionSsr
函数如下所示:
import GetServerSidePropsContext, GetServerSidePropsResult, NextApiHandler from 'next'
import withIronSessionApiRoute, withIronSessionSsr from 'iron-session/next'
import IronSessionOptions from 'iron-session'
const IRON_OPTIONS: IronSessionOptions =
cookieName: process.env.IRON_COOKIE_NAME,
password: process.env.IRON_PASSWORD,
ttl: 60 * 2,
function withSessionRoute(handler: NextApiHandler)
return withIronSessionApiRoute(handler, IRON_OPTIONS)
// Theses types are compatible with InferGetStaticPropsType https://nextjs.org/docs/basic-features/data-fetching#typescript-use-getstaticprops
function withSessionSsr<P extends [key: string]: unknown = [key: string]: unknown >(
handler: (
context: GetServerSidePropsContext
) => GetServerSidePropsResult<P> | Promise<GetServerSidePropsResult<P>>
)
return withIronSessionSsr(handler, IRON_OPTIONS)
export withSessionRoute, withSessionSsr
【讨论】:
以上是关于在 Next.js 中创建一个 HOC(高阶组件)进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章