Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support get CSRF_TOKEN via cookie #515

Closed
oanhnn opened this issue Sep 16, 2017 · 5 comments
Closed

Support get CSRF_TOKEN via cookie #515

oanhnn opened this issue Sep 16, 2017 · 5 comments

Comments

@oanhnn
Copy link

oanhnn commented Sep 16, 2017

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

@ghost
Copy link

ghost commented Nov 1, 2017

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

@richfoxton
Copy link

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

@driesvints
Copy link
Member

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.

@tsewaiho
Copy link

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!

@driesvints
Copy link
Member

This has actually already been added in #1069 it seems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants