passport: CreateFreshApiToken don't create the laravel_token cookie
I don’t known if this is the best place for this, but I’m struggling with this for two days, almost giving up!
So, following up the “Consuming Your API With JavaScript” section of documentation, I added the \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class in App\Http\Kernel.php (in web), and authenticated my user with axios.
window.authorize = function() {
let data = {
grant_type: 'password',
client_id: 2,
client_secret: 'fNoSz3LnZYnHE1MHgUV3FlJ3gWEpACd5gCvJEW2p',
username: 'abc@def.com',
password: 'admin',
scope: '',
};
window.axios.post('/oauth/token', data).then(r => {
if (r.status === 200) {
console.log('got a valid response');
console.log(r.data);
} else {
console.log(r.status);
}
}).catch(r => {
console.error(r.data);
});
};
I got a access_token and a refresh_token, but never got a response to set a laravel_token cookie (only laravel_session).
When I try to check the authentication, with the following code, I got a 401 Unauthenticated:
window.check = function() {
window.axios.get('/api/user').then(r => {
console.log(r.data);
});
};
I’m using the bootstrap.js example I got with Laravel 5.4:
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
}
Axios is sending the following headers:
- X-CSRF-TOKEN
- X-Requested-With:XMLHttpRequest
- X-XSRF-TOKEN
Debugging the CreateFreshApiToken middleware, on handle function, the return value is always false on function shouldReceiveFreshToken.
for some reason, the $this->guard is always null, so this function is always false:
protected function requestShouldReceiveFreshToken($request)
{
return $request->isMethod('GET') && $request->user($this->guard);
}
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 30 (3 by maintainers)
@tobecwb @lady-ady @BobbyBorisov can you all three show me what you are returning from your controller method? Please realize that the
laravel_tokencookie will only be set if:GETrequestX-CSRF-TOKEN&X-Requested-Withheaders (default on a base Laravel install)Please share the code from your controller which you’re returning from the get request you’re performing. I have a slight hunch at what’s going on but need more info.
Hi there,
if you pay attention, you’ll see that your request must be GET in order to the middleware to create an API token.
You can easily get the token by sending a dummy GET request to your site AFTER you’re logged in.
I inspect all the way the authentication goes. in Authenticate.php autenticate(array $guards), when doing $this->auth->guard($guard)->check(), it return false, then I go to have a look on the TokenGuard.php decodeJwtTokenCookie($request), it will decrypt the passport cookie -> which the laravel_token, and it gives out DomainException: Malformed UTF-8 characters. I think it is the root cause of why the authentication failed. After all, I check the laravel_token in jwt.io, it says “Looks like your JWT header is not encoded correctly using base64url”
I couldn’t get it to work, had to use a custom implementation. Thanks for helping out though @skyrpex!
Do you guys think it’s because the login is part of the SPA as opposed to the default laravel login page, or should it be able to work since we post the required fields anyway from the SPA login page? I am really trying to keep the whole login/register experience on the SPA side 100%, and only post the values to the api controller. This is much better UX than having
/loginand/registeron the laravelweb.phpserver side decoupled from the SPA client side routing, no awkward refreshes and lightning fast.I read many threads about SPA and laravel passport authentication, which say they should be decoupled in order to store the encrypted jwt in session cookie (but the threads are older, and maybe there is a new way with the
CreateFreshApiToken), but I am trying to do it from just the SPA and jwt in session cookie as I mentioned. We don’t want to save the jwt to local storage for obvious security purposes, even though the Bearer Authorization header works 00% on client, but is not secure.So can it be 100% client side SPA login with
CreateFreshApiTokenhandling the jwt token security via sessions?I’ve been stuck on this for two full days and it’s critical to know how to proceed, since we launch soon.
Please let me know if anyone has any idea.