Passport: Support get CSRF_TOKEN via cookie

Created on 16 Sep 2017  路  5Comments  路  Source: laravel/passport

I think we change how to get csrf token to support Axios send csrf via cookie (X-XSRF-TOKEN)

https://github.com/laravel/passport/blob/91671e53ffd88cb1b7b5b53047f7eee2ac0d172f/src/Guards/TokenGuard.php#L194-L210

enhancement

Most helpful comment

@GJordan904 Any chance of making this a pull request? I've run in to this issue too.

All 5 comments

I agree and to clarify, Axios and other Http clients like Angulars HttpClientModule automatically check for the XSRF-TOKEN cookie and set the X-XSRF-TOKEN header on outgoing requests. When Passport authenticates a request it checks that the CSRF token was sent with the request and that it matches the one in the decoded token but it fails to check for the XSRF Token, decode it and check its validity.

To solve the problem I have extended Passports TokenGuard with the following minor changes:

protected function validCsrf($token, $request)
{
    $isCsrf = false;
    $isXsrf = false;
    if($csrf = $token['csrf']) {
        $isCsrf = hash_equals(
            $token['csrf'], (string) $request->header('X-CSRF-TOKEN')
        );
        if($request->hasHeader('X-XSRF-TOKEN')) {
            $isXsrf = $this->encrypter->decrypt($request->header('X-XSRF-TOKEN')) === $csrf;
        }
    }
    return $isCsrf || $isXsrf;
}

@GJordan904 Any chance of making this a pull request? I've run in to this issue too.

Hmm yeah we should be able to match the behavior of the getTokenFromRequest on the VerifyCsrfToken middleware. I'll mark this as a feature request. Feel free to send in a PR to the master branch.

I have written a middleware as my temporary solution.

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Cookie\Middleware\EncryptCookies;
class AddCsrfHeader
{
    protected $encrypter;
    public function __construct(Encrypter $encrypter)
    {
        $this->encrypter = $encrypter;
    }
    public function handle($request, Closure $next)
    {
        if ($header = $request->header('X-XSRF-TOKEN')) {
            $token = $this->encrypter->decrypt($header, static::serialized());
            $request->headers->set('X-CSRF-TOKEN', $token);
        }
        return $next($request);
    }
    public static function serialized()
    {
        return EncryptCookies::serialized('XSRF-TOKEN');
    }
}

Add this middleware to api middleware group

'api' => [
  'throttle:60,1',
  'bindings',
  \App\Http\Middleware\AddCsrfHeader::class,
]

Make its priority higher than authenticate

protected $middlewarePriority = [
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \App\Http\Middleware\AddCsrfHeader::class,
    \App\Http\Middleware\Authenticate::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];

Done!

This has actually already been added in https://github.com/laravel/passport/pull/1069 it seems.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Patskimoto picture Patskimoto  路  3Comments

seriousjelly picture seriousjelly  路  3Comments

mehrancodes picture mehrancodes  路  3Comments

huiyonghkw picture huiyonghkw  路  3Comments

duccanh0022 picture duccanh0022  路  3Comments