简体   繁体   中英

How to create HOC for auth in Next.js?

I want to create basic Next.js HOC for authentication. I searched but I didn't figure it out.

I have an admin page in my Next.js app. I want to fetch from http://localhost:4000/user/me and that URL returns my user. If user data returns, component must be rendered. If data didn't return, I want to redirect to the /admin/login page.

I tried this code but that didn't work. How can I solve this issue? Also can I use useSWR instead of fetch ?

const withAuth = (Component, { data }) => {
  if (!data) {
    return {
      redirect: {
        destination: "/admin/login",
      },
    };
  }
  return Component;
};

withAuth.getInitialProps = async () => {
  const response = await fetch("http://localhost:4000/user/me");
  const data = await response.json();
  return { data };
};

export default withAuth;
const AdminHome = () => {
  return ();
};
export default withAuth(AdminHome);

Are you using any JS library for auth? Here is auth0 doc that might give you some ideas.

Based on the answer from Create a HOC (higher order component) for authentication in Next.js , you can create a re-usable higher-order function for the authentication logic.

If the user data isn't present it'll redirect to the login page. Otherwise, the function will continue on to call the wrapped getServerSideProps function, and will return the merged user data with the resulting props from the page.

export function withAuth(gssp) {
    return async (context) => {
        const response = await fetch('http://localhost:4000/user/me');
        const data = await response.json();
        
        if (!data) {
            return {
                redirect: {
                    destination: '/admin/login'
                }
            };
        }

        const gsspData = await gssp(context); // Run `getServerSideProps` to get page-specific data
        
        // Pass page-specific props along with user data from `withAuth` to component
        return {
            props: {
                ...gsspData.props,
                data
            }
        };
    }
}

You can then use it on the AdminHome page to wrap the getServerSideProps function.

const AdminHome = ({ data }) => {
    return ();
};

export const getServerSideProps = withAuth(context => {
    // Your normal `getServerSideProps` code here
    return { props: {} };
});

export default AdminHome;

If you're looking for the typescript version:

withAuth.ts

export function withAuth(gssp: GetServerSideProps): GetServerSideProps {
  return async (context) => {
    const { user } = (await getSession(context.req, context.res)) || {};

    if (!user) {
      return {
        redirect: { statusCode: 302, destination: "/" },
      };
    }

    const gsspData = await gssp(context);

    if (!("props" in gsspData)) {
      throw new Error("invalid getSSP result");
    }

    return {
      props: {
        ...gsspData.props,
        user,
      },
    };
  };
}

Home.tsx

export const getServerSideProps = withAuth(async (context) => {
  return { props: {} };
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM