简体   繁体   English

Next.js 和 csrf 令牌返回服务器端错误

[英]Next.js and csrf token returns server side error

I'm using the library next-csrf ( https://github.com/j0lv3r4/next-csrf ) to protect api routes in my next.js application.我正在使用库 next-csrf ( https://github.com/j0lv3r4/next-csrf )来保护我的 Z32D3463FBFCE7273B003F2D89A8 应用程序中的 api 路由。

I followed the documentation but the api now returns an error 500:我遵循了文档,但 api 现在返回错误 500:

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

Here's the code:这是代码:

/lib/csrf.js : /lib/csrf.js

import { nextCsrf } from 'next-csrf';

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

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

Page that calls the api:调用 api 的页面:

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 works and I can see the header in the network tab:令牌有效,我可以在网络选项卡中看到 header:

在此处输入图像描述

Api route: Api路线:

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);

There's also another thing happenig.还有另一件事发生。 If I try to call the api from postman the api works.如果我尝试从 postman 调用 api,则 api 有效。 I can see that there's a cookie with the "XSRF-TOKEN" value inside that I haven't set in any way, so I'm not sure where Postman is getting it:我可以看到里面有一个带有“XSRF-TOKEN”值的 cookie,我没有以任何方式设置,所以我不确定 Postman 从哪里得到它:

在此处输入图像描述

How can I fix this?我怎样才能解决这个问题?

  1. Such error message is possible only in the case when cookie value is not a string .只有在cookie 值不是字符串的情况下才可能出现此类错误消息。 And according to next-csrf getCookie code the cookie value may be not a string, only in case when there are some cookies but not the required one.并且根据 next-csrf getCookie 代码,cookie 值可能不是字符串,仅在有一些 cookies 但不是必需的情况下。

And there is an error in next-csrf transpilation which makes code from line 52 to move to the line 26 , skipping some checks and changing the program logic.并且在next-csrf转译中有一个错误,它使第52行的代码移动到第26行,跳过了一些检查并更改了程序逻辑。 You can see it here https://unpkg.com/browse/next-csrf@0.1.2/dist/next-csrf.js , at the line 1891.你可以在这里看到它https://unpkg.com/browse/next-csrf@0.1.2/dist/next-csrf.js ,在第 1891 行。

Now:现在:

  • To avoid this case you should send first request without any cookie set up.为了避免这种情况,您应该在没有设置任何 cookie 的情况下发送第一个请求。 It seems like this is what Postman does and this is why it works in Postman.看起来这就是 Postman 所做的,这就是它在 Postman 中工作的原因。
  • A fix in the code of getCookie is required.需要对 getCookie 的代码进行修复。 The function should return string, not string or undefined. function 应该返回字符串,而不是字符串或未定义。

Also I wouldn't recommend you to use this library without proper transpilation issue resolution.此外,如果没有适当的转译问题解决方案,我不建议您使用此库。

  1. Postman receives cookie, because next-csrf middleware defines set-cookie header, if there is no one in the first request. Postman接收cookie,因为next-csrf中间件定义了set-cookie header,如果第一个请求中没有。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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