Restrict pages to not be directly accessible

Viewed 45

I have a Next.js project that I would like to implement a success page for (think about cart checkout or form submission). However, currently the page is directly accessible by just typing in the page URL. I have considered just using stateContext with a state field like successCanRedirect, setSuccessCanRedirect and setting the successCanRedirect after I receive the 200 back from the form submission. I was just thinking I could check if successCanRedirect was true when loading the success page then redirect to / if false. Just seeing if there was another way to do it.

1 Answers

You can restrict access to your success page by comparing a query parameter with the one from database. For instance, let's say you send the user to your success page from your checkout page with a query parameter named 'order_id'. But if someone tries to access your success page directly typing url, there will be no query parameter named 'order_id' and we want such an action to end with navigating to your home page (/). Even if they know query parameter name, they will not be aware of the order id. This is our starting point.

Code to send the users from checkout page to success page. This is our normal flow, user makes a successful payment and get order information.

import Router from 'next/router';

Router.push({
  pathname: '/success',
  query: {
    order_id: JSON.stringify(order_id),//this is the order id of new purchase
  }
}, '/success');//we do not want query parameters to be visible

Now, we should check if a query parameter named 'order_id' exists and compare with the one from database and then take action accordingly in our success page.

import { GetServerSideProps } from 'next';
import { withRouter } from 'next/router';

export const getServerSideProps: GetServerSideProps = async (ctx) => {
  if (!ctx.query.hasOwnProperty('order_id')) {
      return {
        redirect: {
          destination: '/',
          permanent: false,
        },
      };
  }
  else {
    let order_id = await fetch('http://locahost/users/' + user_id + '/last_order_id');//get the last successful purchase id of the user
    if (order_id !== ctx.query.hasOwnProperty('order_id')) {
      return {
        redirect: {
          destination: '/',
          permanent: false,
        },
      };
    }
  }
  return {
    props: {},
  };
};

export default withRouter(Checkout);
Related