首页 > 解决方案 > 如果我使用 httpOnly cookie,如何构建一个 HOC 来保护路由?

问题描述

我将令牌存储在 httpOnly cookie 中,但是当我想构建一个 HOC 来保护路由时,无法直接在组件内部访问 cookie,我必须在服务器端进行,我试图做一些事情像这样,但它不起作用:

import Cookie from "cookies";
const withAuth = (Page) => {
  Page.getServerSideProps = async ({ req, res }) => {
    const cookie = new Cookie(req, res);
    const token = cookie.get("token");
    if (!token)
      return {
        redirect: {
          permanent: false,
          destination: "/login",
        },
      };
    return {
      props: {
        token,
      },
    };
  };
  return Page;
};

export default withAuth;

标签: next.js

解决方案


getServerSideProps功能仅适用于页面,不适用于组件。

以下代码段应该可以帮助您创建一个 HOC 进行身份验证。这个例子使用了闭包的概念。我会打电话给这个的withAdministrator.jsx

// withAdministrator.jsx
export default (GetServerSidePropsFunction) => async (ctx) => {
  // 1. Check if there is a token.
  const token = ctx.req.cookies?.jwt || null;

  // 2. Perform an authorized HTTP GET request to the private API to get user data.
  // In here, assume that 'getAuth' is a function to perform authorized GET request using the token value in the 'Authorization' header.
  const { data } = await getAuth(`${process.env.PRIVATE_API_URL}/api/v1/users/user`, token);

  // 3. If there is no user, or the user is not an admin, then redirect to unauthorized.
  if (!data || data.role !== 'admin') {
    return {
      redirect: {
        destination: '/unauthorized',
        permanent: false,
      },
    };
  }

  // 4. Return via closure: 'GetServerSidePropsFunction'.
  return await GetServerSidePropsFunction(ctx);
};

你会这样称呼它。假设您要访问该/admin路线。

export const getServerSideProps = withAdministrator(() => {
  return {
    props: {},
  };
});

const Admin = () => {
  return (
    <YourComponent />
  );
};

你可以在返回的函数中做任何你想做的事情。例如,您可能希望在对用户进行身份验证后获取数据。

进一步阅读:Next.js 中的数据获取


推荐阅读