lexik / LexikJWTAuthenticationBundle

JWT authentication for your Symfony API
MIT License
2.52k stars 610 forks source link

Get Cookie sent after login on each request #723

Closed lionelkimbs closed 4 years ago

lionelkimbs commented 4 years ago

Hello, I have a weird behaviour with my API. I have a front build in React and back in SF4 with APIPLatform. I made authentication system with this bundle (lexik/jwt). When a user try to log, it works, I send in header response a Set-Cookie BEARER=blaBlaBLA; expires=Mon, 02-Mar-2020 15:57:22 GMT; Max-Age=3600; path=/; samesite=lax But after that, when the React app tries going to secured routes, like /api/users/1, my SetCookie isn't sent in the request.

I don't know if it's clear. Someone have an idea please ? How to get Setcookies on request after a succeed login.

TheEyes007 commented 4 years ago

Hello @lionelkimbs,

I have the same problem et I wait a solution with the next update of the bundle. Maybe, a contributor could help us.

Regards.

flohw commented 4 years ago

Hello,

I had the issue too in my Anglar and AngularJS project. I think this is because the requests are handled by javascript and not by the browser. Si you have to set the cookie manually.

I found ngx-cookie-service for Angular and it seems React has two modules : react-cookie and react-cookies.

I let you choose and make your own research on the module you need as I don't know React.

TheEyes007 commented 4 years ago

Hello @flohw,

Thanks for you answer. I use Angular too for my personnal project to learn this framework. Now, I have my JWT in Cookie (Request Headers). This JWT is read by my symfony application but... When I use JWT in localStorage, no problem. When I use JWT in cookie, my symfony application say, 'Invalid JWT token'.

I continue my investigation.

Good afternoon.

flohw commented 4 years ago

Hi @TheEyes007,

Here are the steps I use to login my user properly and set the cookie:

Unfortunately the only code I have is from my legacy app which is built with AngularJS.

// This is in the AuthenticationService. The login method is called when user submit the login form
angular.module('auth_service', [])
    .service('AuthenticationService', ['$http', 'SessionService', function ($http, SessionService) {
        this.login = credentials => $http.post('/api/login_check', credentials)
            .success(data => SessionService.initializeSession(data))
            .error(() => SessionService.invalidateSession());
}]);

// This is the part you may be interested in
angular.module('session', [])
    .service('SessionService', ['$cookies', function ($cookies) {
        this.initializeSession = function (data) {
            $cookies.put('JWT', data.token);
            // You may want to set a user property here to easily retrieve here anywhere
        };
    }]);

Please note that the $cookies service used in my AngularJS app is provided by the ngCookie module which is an equivalent of the ngx-cookie-service mentioned earlier. Also I configured the service to store non secured cookie and set the path to /. I can't remember yet why I needed to store insecure cookie.

I hope you would be able to fit the code and explanations to your need as I can't be more explicit :slightly_smiling_face:

TheEyes007 commented 4 years ago

Hi @flohw,

Thanks for you answer. I retry install my project and i have the same problem. I though your method was not secure because we create cookie client side. But, we can protect it too so I use your method to advance in my project.

Thank a lot. :)

flohw commented 4 years ago

I just found this question on stackoverflow. Maybe you can take a look. Tell me if it works, I may update my code too. https://stackoverflow.com/questions/22432616/why-is-the-browser-not-setting-cookies-after-an-ajax-request-returns

Also, the only unsecured thing I do is to set the option secure to false. I don't think setting a cookie via javascrit is not secure. The cookie is managed by the browser then, not by javascrit.

TheEyes007 commented 4 years ago

Hi @flohw ,

So. I have any investigation and client side, it's not possible to put a httponly rules by generating cookie with javascript.

That's why, I use this video https://www.youtube.com/watch?v=uboIb2__qqs and this project https://github.com/konshensx16/symfony-todo-backend to help me.

I install it and it's ok. Next, I install a new project symfony with the last version LTS and without restbundle and nelmio cors. It's ok too.

Now, I check all step by reorganizing the project to respect my rules (Action/Domain/Responder) to target my error. If it's ok, i publish it in my repo. There will be login_check, refresh_token and an example of route.

Thanks you for you help. I contact you when I do it. Good afternoon.

TheEyes007 commented 4 years ago

Hello @flohw ,

I fix my error. In fact, no problem with authentication by cookie. My problem came from my user profile Action/Responder. From JWT, I have my username. This username is used to get profile information. But, in my service, the JWT is recovered by authorization headers, not by cookie, that why I have the message JWT invalid token, value was empty.

Repository : https://github.com/TheEyes007/lexikJWTTest

Regards.

flohw commented 4 years ago

Closing as issue is resolved and #646 adds more details and a note https://github.com/lexik/LexikJWTAuthenticationBundle/issues/646#issuecomment-590456742