Problem encountered when Next.js and CSRF token interact on the server

I've integrated the next-csrf library (https://github.com/j0lv3r4/next-csrf) into my next.js app to safeguard api routes.

Despite following the documentation, I'm encountering a 500 error with the following message:

{"message":"Signed cookie string must be provided."}

Below is the code snippet:

/lib/csrf.js:

import { nextCsrf } from 'next-csrf';

const options = {
  secret: `${process.env.CSRF_SECRET}`,
};

export const { csrf, csrfToken } = nextCsrf(options);

The page making the api call looks like this:

import { useState, useEffect } from 'react';
import axios from 'axios';
import { withRouter } from 'next/router';

import { Page, PostBlock } from '@/components';


const Main = ({ router, csrfToken }) => {
  const [postsData, setPostsData] = useState({ posts: [], page: 0, pages: 0 });

  function fetchData() {
    axios
      .get('/api/articles', {
        headers: { 'XSRF-TOKEN': csrfToken },
        params: {
          page: router.query?.page,
          lang: router.locale,
          tag: router.query.tag,
        },
      })
      .then(response => {
        setPostsData(response.data);
      })
      .catch(error => console.log(error));
  }

  useEffect(() => {
    fetchData();
  }, []);


  return (
    <Page title='Home' className='home-template'>
      <div id='grid' className='post-grid'>
        {postsData.posts?.map(post => {=
          return (
            <PostBlock
              featured={post.featured}
              key={post.slug}
            />
          );
        })}
      </div>
    </Page>
  );
};

export default withRouter(Main);

The token is functioning correctly as evidenced by the header in the network tab:

https://i.sstatic.net/bAkvu.png

For the api route section, the relevant code is as follows:

import { getPosts } from '../../../utils/index';

import { csrf } from '../../../lib/csrf';

function handler(req, res) {
  const {
    query: { page, lang, tag },
    method,
  } = req;

  switch (method) {
    case 'GET':
      const posts = getPosts(page, lang, tag);
      res.status(200).json(posts);
      break;
    default:
      break;
  }
}

export default csrf(handler);

Additionally, when attempting to make an api call using Postman, it works. Notably, there's a cookie with the "XSRF-TOKEN" value present despite not being explicitly set, posing uncertainty on its origin:

https://i.sstatic.net/Uovvs.png

What steps can I take to address this issue?

Answer №1

  1. When encountering such an error message, it indicates that the cookie value is not a string. This issue arises when there are multiple cookies present but not the required one, as explained in the getCookie code.

Furthermore, a transpilation error in next-csrf causes the code to shift from line 52 to line 26, resulting in skipped checks and altered program logic. The issue can be observed here at line 1891.

Current Solution:

  • To prevent this scenario, it is advisable to make the initial request without setting any cookies. This approach, similar to Postman's method, ensures functionality in testing environments.
  • An essential fix for the getCookie function is needed to ensure it returns a string rather than possibly returning undefined or another type.

It is strongly advised against using this library until the transpilation issues have been properly addressed.

  1. Postman successfully receives cookies due to next-csrf middleware including a set-cookie header if it is absent in the initial request.

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

Expand the <div> by clicking on it, then hover away to return it to its normal size

One interesting feature I have on my website is a <div> that expands when clicked, and returns to normal size with another click. However, I am looking for something a bit different... What I want is for the <div> (with the class name .topHead ...

What is the purpose of specifying http://localhost:3000 when accessing API routes in Next.js?

I created an API route within the pages directory of my NextJS project. It is functioning properly as I am able to retrieve data by directly accessing the URL like http://localhost:3000/api/tv/popular. My goal is to fetch this data using getStaticProps and ...

Chrome reload causing page to automatically scroll to bottom on my website

Could really use some assistance in solving this problem as I am completely stumped. I've noticed an issue on one of my websites when pages are reloaded. Every now and then (not consistently, which adds to the confusion), upon refreshing a page, it ...

The following middleware fails to transmit cookies received from the server

After a successful login to my Django backend, an httpOnly cookie is returned which is necessary for accessing protected routes in the Next app. To manage this, I have implemented a middleware that checks if a user is trying to access a protected route. If ...

Steps to successfully implement onClick functionality in html within C# server side code

I'm having trouble with my onClick function. When I click, nothing happens and there are no errors to help me diagnose the issue. var data = new FormData(); data.append("cart_list", new_cart); $.ajax({ url: "@Url.Action ...

Configuration file for collaborative component library within a Turbo repository

Currently, I am in the process of transitioning my Next.js application to a Turborepo monorepo structure and dividing the app's concerns into separate Next apps. Within this setup, there is a shared component library that will be utilized across all a ...

Is it possible to transform all scripts into a React component? (LuckyOrange)

I am currently working on converting the script for a specific service (http://luckyorange.com/) into a component. The instructions say to place it in index.html within the public folder, but that appears to be insecure. I'm uncertain whether this tas ...

The File is not being successfully sent to the controller in MVC due to AJAX returning an undefined value

I recently created an AJAXUpload method within a cshtml file in my C# MVC project: function AjaxUpload(url, method, data, successFunction, errorFunction, skipErrorDlg) { $.ajax({ contentType: false, processData: false, url: url ...

Why Are My JavaScript GET Request Parameters Displaying as Strings Rather Than Numbers?

Currently, I am in the process of developing a REST API where one of the defined routes looks like this: router.get("/objects/:id?/:val1?/:val2?", getObject); Specifically, my request from Postman appears as follows: http://localhost:8000/objects?val1= ...

Invoking Javascript Functions using their names

Suppose I have the following element on my page... <span data-function="DoSomething">Click</span> ... and then add the following to my page header... $(document).ready(function() { $('[data-function]').each(function() { ...

Updating results in Angular.js based on variable changes

After setting some data in the window, I am facing issues with updating an angular.js table created using the smart table module/plugin. The data is structured like this: window.checker={};window.checker.checked = [{'ip':9,'port':0}] ...

Why can't JQuery/javascript's dynamic gallery's images be used as buttons instead of links?

I've been struggling with my online portfolio for several nights as I build my website. Despite exhaustive internet searches, I couldn't quite articulate my problem in words and tried multiple workarounds. To see the issue, please visit the beta ...

Encountering a problem when trying to dynamically change the value in a dropdown menu with Angular.js

Having an issue where two drop down lists have the same value. When I set a value to the first drop down list, the second one also takes that value. Below is my code for reference: <div class="col-md-6"> <div class="input-group bmargindiv1 col-md ...

The process of retrieving keys and values from localStorage in html5

I have stored some important key-value pairs in local storage. Now I need to retrieve both the keys and values, and then display them by appending the values in a list item (li). Currently, my attempt at this looks like: for (var i = 0; i < localStorag ...

Component in NextJS fails to retrieve data upon mounting

I am currently working with Next.js and have a single page - index.js. Within this page, I am importing a component called Products, which contains a GraphQL request to fetch data from an endpoint. When trying to access the products.map property in my cod ...

In the realm of HTML Canvas, polygons intricately intertwine with one another

Currently, I am attempting to create multiple polygons from a large JSON file. Instead of being separate, the polygons seem to be connected in some way. The project is being developed in next.js. Below are the relevant code snippets: Canvas.tsx // ../co ...

Engaging User Forms for Enhanced Interactivity

I'm in the process of developing an application that involves filling out multiple forms in a sequential chain. Do you have any suggestions for creating a more efficient wizard or form system, aside from using bootstrap modals like I currently am? C ...

I need to search through a tree structure in typescript based on a specific value without encountering a maximum stack call exceeded error

How can I perform a value-based search on a complex tree structure in TypeScript without encountering the maximum stack call exceeded error? I am attempting to navigate through an expandable tree using TypeScript, and I will provide the code snippet below ...

There seems to be a contradiction in my code - I am returning a Promise but TypeScript is throwing an error saying that the

I currently have a function that retrieves a bot's inventory on the Frontend fetchBotInventory() { this.socket.emit('fetch bot inv'); this.socket.on('bot inv', (botInventory) => { return new Promise((resolve, re ...

The footer should remain at the bottom of the page without being permanently fixed

Is there a way to keep the bootstrap footer at the bottom without fixing it in place? In the code example below, the footer should always appear at the bottom. The white space after the footer should come before it. Using sticky-bottom achieves this, but ...