解决laravel中的令牌不匹配错误的正确方法是什么? [英] What is the right way to resolve token mismatch error in laravel?

查看:307
本文介绍了解决laravel中的令牌不匹配错误的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我已经将laravel更新为5.4,所以我不断得到:

since I've updated laravel to 5.4 I constantly get:

TokenMismatchException in VerifyCsrfToken.php line 68

抛出异常.经过一番挖掘和阅读了大量的帖子和github问题后,我发现我的令牌不匹配:).关键是我的laravel应用设置了令牌"XSRF-TOKEN"的加密版本,而不是其普通(X-CSRF-TOKEN)副本,并且助手csrf_token()吐出了普通令牌,因此令牌不匹配.为什么当我得到XSRF-TOKEN(缺少X-)时,为什么文档中提到X-XSRF-TOKEN令人困惑呢?所以问题是:

exception thrown. After some digging and reading through a whole lot of posts and github issues I've figured that my tokens aren't matching :). The point is that my laravel app sets the encrypted version of the token "XSRF-TOKEN" instead of its plain (X-CSRF-TOKEN) counterpart and the helper csrf_token() spits out the plain token hence mismatching tokens. Confusing though why documentation mentions X-XSRF-TOKEN when I get XSRF-TOKEN (missing X-) instead? So the questions are:

  1. 缺少的"X-"有什么意思吗?
  2. 如何将令牌的加密版本更改为普通版本? (与问题3无关)
  3. 我什至应该尝试从已加密的令牌中制作一个普通令牌,还是最好对csrf_token()进行加密? (因为连接是加密的,它甚至有关系吗?)
  4. \MiddleWare\EncryptCookies.php$excepted下列出"XSRF-TOKEN"是可行的选择,还是您可以建议一个更好的解决方案? (这使我们回到了问题3)
  1. Has the missing "X-" some meaning?
  2. How do I change the encrypted version of the token to the plain one? (regardless of the question #3)
  3. Should I even try to make a plain token out of the encrypted one or is it better to encrypt csrf_token() instead? (Does it even matter, since the connection is encrypted?)
  4. Is listing "XSRF-TOKEN" under $excepted in the \MiddleWare\EncryptCookies.php a viable option or could you suggest a better solution instead? (which sort of brings us back to the question #3)

对于许多问题我深表歉意,并在此先感谢!

I'm sorry for so many questions and thanks in advance!

在多次重读我的问题后,我得出的结论是它们不够清楚,也没有遵守标题.我的问题是令牌不匹配,我认为清除我的疑虑将使我找到解决方案,我感谢@ThomasMoors的耐心和帮助.我会接受他的回答,尽管我以不同的方式解决了我的问题,但正是他的帮助使我找到了解决方案!另外,我还发布了自己的答案,该答案描述了我如何解决自己的问题,以帮助遇到类似问题的其他人!

After rereading my questions several times I came to conclusion that they weren't clear enough and didn't complied with the title. My problem were the mismatching tokens and I thought having my doubts cleared would lead me to a solution, I thank @ThomasMoors for his patience and help. I will accept his answer, and although I've solved my problem a different way, it was his help that led me to the solution! I've additionally posted my own answer which describes how I've solved my issue to help others having similar issues!

推荐答案

会话的生存位置取决于您的配置

The function that checks the token tries to find it (1) inside a request plain with the key _token, if it does not find it, it will try to look inside (2) the request headers with the key X-CSRF-TOKEN. The token to match is stored inside the session, where the session lives depends on your config.

    /**
     * Determine if the session and input CSRF tokens match.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function tokensMatch($request)
    {
        $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
        if ( ! $token && $header = $request->header('X-XSRF-TOKEN'))
        {
            $token = $this->encrypter->decrypt($header);
        }
        return StringUtils::equals($request->session()->token(), $token);
    }

Q :缺少的"X-"是否有意义?

A :Laravel将当前CSRF令牌存储在XSRF-TOKEN cookie中 包含在框架生成的每个响应中.您可以使用 cookie值来设置X-XSRF-TOKEN请求标头.

A: Laravel stores the current CSRF token in a XSRF-TOKEN cookie that is included with each response generated by the framework. You can use the cookie value to set the X-XSRF-TOKEN request header.

此cookie主要是为了方便起见而发送的,因为有些JavaScript 框架和库(例如Angular和Axios)会自动放置 其值在X-XSRF-TOKEN标头中.

This cookie is primarily sent as a convenience since some JavaScript frameworks and libraries, like Angular and Axios, automatically place its value in the X-XSRF-TOKEN header.

Q :如何将令牌的加密版本更改为普通版本? (与问题#3无关)

A :就像上面的代码一样(来自github),\Illuminate\Contracts\Encryption\Encrypter具有一个名为decrypt()的函数,可以执行此操作

A: As in the code above (from github) \Illuminate\Contracts\Encryption\Encrypter has a function called decrypt() that does this

Q :我什至应该尝试从加密的令牌中制成普通令牌,还是最好加密csrf_token()? (因为连接是加密的,它甚至有关系吗?)

A :没关系,因为令牌中没有数据,它只是源于您网站的合法请求的标识符,而不是来自其他域的ajax/xhr调用.进一步了解 https://en.wikipedia.org/wiki/Cross-site_request_forgery

A: It does not matter, because the token has no data inside it, it is just an identifier of a legit request originating from your site and not some ajax/xhr call from another domain. read more on https://en.wikipedia.org/wiki/Cross-site_request_forgery

Q :在$ MiddleWare \ EncryptCookies.php中的$ X下列出"XSRF-TOKEN"是否可行,或者您可以建议一个更好的解决方案吗? (这使我们回到问题3)

A :令牌没有理由随时都位于cookie中,是吗?

A: The token has no reason to be inside a cookie at any time, does it?

从5.0到5.4似乎确实有些已更改.现在看起来像这样:

It seems that from 5.0 to 5.4 indeed something has changed in the function above. It looks like this now:

 protected function tokensMatch($request)
    {
        $token = $this->getTokenFromRequest($request);
        return is_string($request->session()->token()) &&
               is_string($token) &&
               hash_equals($request->session()->token(), $token);
    }

这篇关于解决laravel中的令牌不匹配错误的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆