Securing routes with server-side validation

I've been experimenting with different methods to secure a route for unauthenticated users, but I'm facing difficulties in implementing it effectively.

One common issue I encountered while attempting authentication from getServerSideProps was the recurring

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
. To work around this, I tried not redirecting from there and instead setting a boolean variable called redirect to handle redirection from the client side. However, now I'm encountering an error saying
No router instance found. you should only use "next/router" inside the client side of your app.
, even though I believe I am working on the client side.

export async function getServerSideProps(ctx: ApiRoutesTypes) {

  const cookie = parseCookies(ctx);

   if (!testCookie.autho) {
     const redirectLogin = true;

     return { props: { redirectLogin } };
   }

  const query = {
    text: 'SELECT fk_users_id FROM tokens WHERE token = $1 AND status = true',
    values: [cookie],
  };
  const userId = (await db.query(query)).rows[0].fk_users_id;
    ...

  return { props: { userId } };
}
export default function Homepage({redirectLogin }){
  const router = useRouter();

  
  if (redirectLogin) {
    router.push('/login');
  }

    ...

}

Is there a solution to this dilemma? If not, what would be the most effective approach to achieve redirection when all my pages heavily rely on getServerSideProps but also require authentication?

Answer №1

When it comes to protecting routes and redirecting users to the login page, there is a key strategy that works effectively:

Utilize a function to establish initial props for a page. Within this function, you can determine whether the page is protected or not.

export const authInitialProps = isProtectedRoute => ({
  req,
  res,
  query: { userId }
}) => {
  const auth = req ? getSessionFromServer(req) : getSessionFromClient();
  const currentPath = req ? req.url : window.location.pathname;
  const user = auth.user;
  const isAnonymous = !user;
  if (isProtectedRoute && isAnonymous && currentPath !== "/signin") {
    return redirectUser(res, "/signin");
  }
  return { auth, userId };
};

The variable isProtectedRoute plays a crucial role in determining if the route is protected. If so, and if the user is not logged in, they will be redirected to the sign-in page. Otherwise, their authentication data will be passed to the page.

If the user is not logged in, they will be directed to the sign-in page.

If the user is logged in, their authentication data will be passed to the page.

To verify if the user is logged in, you can follow these two approaches:

  1. Server Side Verification-
export const getSessionFromServer = req => {
  if (req.user) {
    return { user: req.user };
  }
  return {};
};
  1. Client Side Verification-
You can utilize cookies or local storage to check for the user's login status.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discovering the art of extracting Embeddable Links from Markdown and displaying them using personalized React Components

I am looking for a way to convert Twitter tags from Markdown to Html. Currently, I am utilizing react-markdown for rendering as shown below import gfm from 'remark-gfm' const content = `#Hello <br/><hr/> <p>Please check out th ...

Encountering a mysterious token error in the backend system

Hello, I am facing an issue with using my token in the application after the user logs in as I am receiving an undefined response in the console. Below are the snippets of code I have been working with. How can I modify my code to successfully access the t ...

Enhance your application by utilizing additional hooks in the Context API

I'm exploring API and react hooks and have a query related to dispatching API fetch to ContextAPI component. Is there a way to consolidate all useState hooks into a single ContextAPI component? The objective is code refactoring by breaking it down int ...

Hooks usage causes disruption in Gatsby and React starting applications

I set up the Gatsby starter application here and everything was running smoothly until I introduced a hook (specifically by swapping out the index.js with the code below): import React, { useState } from 'react'; export default () => { con ...

Tips for preventing the inheritance of .css styles in React

I'm facing an issue with my react application. The App.js fragment is displayed below: import ServiceManual from './components/pages/ServiceManual' import './App.css'; const App = () => { return ( <> ...

Create a continuous integration pipeline utilizing Azure DevOps platform

During my attempt to create a React application, I encountered an error while building the Azure pipeline using Azure DevOps. View the error image from the Azure pipeline in Azure DevOps The code for the azure-pipeline.yml file can be found in my GitHub ...

Upon sending a POST request to http://localhost:5000/getData, a 404 error (Not Found) was encountered while using axios

As a newcomer to react and node.js, I have set up a fake server running on port 5000 with an API (http://localhost:5000/getData) that contains a hardcoded array of objects. My goal is to add a new object to this API from my react frontend running on port 3 ...

Transform the selected component in Material-UI from being a function to a class

Hello, I am currently learning about React and I have started using the select button from material-ui. The code I found on the material ui page is for a functional component, but I am more comfortable with class components. Here is the code snippet provid ...

Tips for creating rounded RaisedButton and TextField:

Despite my efforts to add style to RaisedButton, I have been unsuccessful. Here is the code snippet I used: <RaisedButton type="submit" label="Submit" style={{container:{borderRadius: "5px"}}} primary/> I also referred to this question, but it did ...

Keystroke to activate Ant Design Select and start searching

I'm currently using the 'react-hotkeys-hook' library and have successfully implemented a hotkey that logs in the console when triggered (via onFocus()). My goal now is to use a hotkey that will open a Select component and add the cursor to i ...

Enhance user interface elements after logging in with Supabase and the latest NextJS version

Currently, I am utilizing NextJS 14 (App Router) along with Supabase Auth (@supabase/ssr) Authentication functions smoothly, but I have specific sections of my UI that should be updated when a user is authenticated. For instance, in my header.tsx componen ...

Tips for creating a stylish ReactJs Header component that stays fixed at the top of the page

Having an issue with my Header component - I want it to remain fixed at the top while scrolling down. Here's the current code: I've attempted using "position = fixed", but it caused my header to resize. Then, I tried setting its width to "width ...

Reverting a React-Select child component back to its default values from the parent component

I am facing an issue with a parent component (Membership) that includes a child component (AboutYou). The parent component handles form submission using a button, which also triggers a reset action. The AboutYou child component contains a React-Select inp ...

What is the best way to implement the Snackbar functionality within a class-based component?

My snackbar codes are not working as expected when I click the "confirm" button. I want the snackbar to appear after clicking the button. Most examples I've seen use functional components, so how can I get the Snackbar to work properly in a class comp ...

Exploring FileReader in conjunction with React and Typescript

I am facing an issue while trying to upload a JSON file using an input element of type file. When I attempt to use the onload method on FileReader in TypeScript, I receive an error message saying "Cannot invoke an object which is possibly 'null'. ...

Expanding the use of tagged template literals for passing additional arguments

Currently, I am utilizing styled-components and creating components through their tagged template literal syntax like this: const Button = styled.button` background-color: papayawhip; border-radius: 3px; color: palevioletred; ` In a specific scenar ...

What is the process for creating static pages that can access local data within a NextJS 13 application?

I recently completed a blog tutorial and I must say, it works like a charm. It's able to generate dynamic pages from .md blog posts stored locally, creating a beautiful output. However, I've hit a roadblock while attempting what seems like a sim ...

Make sure that "X" is always displayed on Autocomplete for removing content

Is there a way to keep the "x" always visible in MUI Autocomplete instead of only showing it on hover? I want the X icon to be displayed constantly, not just when hovering over the dropdown. To better illustrate my question, you can refer to this example: ...

Leveraging Nodemailer on Heroku

I have deployed a Next.js app with Heroku at . The app includes a contact form with a submit button that successfully sends an email when I run it locally using npm install, npm run build, npm start. However, when I try to use the app on the Heroku URL, it ...

The script tag in Next.js is not functioning properly, as it is throwing a ReferenceError stating that "

I have attempted numerous times using different methods but the error remains consistent. I would appreciate some guidance on this issue. import Head from 'next/head' import Script from 'next/script' export default function Home() { ...