What is the right way to resolve token mismatch error in laravel?

╄→尐↘猪︶ㄣ 提交于 2019-12-04 16:00:24

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: Has the missing "X-" some meaning?

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.

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: How do I change the encrypted version of the token to the plain one? (regardless of the question #3)

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

Q: 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?)

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

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

UPDATE

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

Although I can't pinpoint the source of my problem (due to lack of experience with the framework) I could finally solve my issue. What I've missed so far is that some middleware classes were moved to a different middleware group in the app/Http/Kernel.php file (my problem probably appeared because order in which they're loaded have changed, or maybe because some of them weren't loaded at all?). I'm pretty sure, that it was the cause of my problem, because I've constantly reloaded my page along with clearing out the cache like suggested on github, it was suggested by jeremykenedy. The suggestion was to call the following commands:

sudo rm -rf storage/framework/sessions/*
sudo php artisan cache:clear
sudo php artisan clear-compiled
sudo composer dump-autoload

which all of you tackling a similar problem have probably encountered hundred of times already. Another suggestion I often found was to change permissions on the storage folder, it might help to some of you tackling a similar problem!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!