Manage user session with jwt

Created on 22 February 2024, 12 months ago
Updated 6 August 2024, 6 months ago

Problem/Motivation

This is a follow-up to ✨ Get the token bearer with the JWT module after log in rest method Needs review . At the moment if you want to use session with a JWT authed user you need to pass along the session cookie as well. This is inefficient and makes it harder than necessary.

Also if we use session then we can link session and jwt token and only auth the user if there is an active session for that JWT so it would solve the expiry on logout problem too.

Steps to reproduce

Try to use the logout token to log a user out with a JWT token it does not work.

Proposed resolution

Add a new middleware that manages the session cookie using information in the JWT. This middleware is provided by a new jwt_sessions module.

Remaining tasks

None

User interface changes

None

API changes

New module jwt_sessions. Does not add any new API itself.

Data model changes

None

πŸ“Œ Task
Status

Needs review

Version

2.0

Component

Code

Created by

πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @alexpott
  • Status changed to Needs review 11 months ago
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    Working on this...

  • πŸ‡ΊπŸ‡ΈUnited States pwolanin

    Can you include the hashed session ID as part of the JWT payload? That can't be used alone to hijack a session, but I worry it's kind of an internal detail that isn't really exposed as part of the session API

    Also - digging into this before, it's seemed hard to bootstrap the session code if there is not an expected cookie.

  • Merge request !13Resolve #3423218 "Manage user session" β†’ (Open) created by alexpott
  • Pipeline finished with Failed
    10 months ago
    Total: 155s
    #131458
  • Pipeline finished with Failed
    10 months ago
    Total: 199s
    #131462
  • Pipeline finished with Failed
    10 months ago
    Total: 172s
    #131482
  • Pipeline finished with Canceled
    10 months ago
    Total: 119s
    #131501
  • Pipeline finished with Failed
    10 months ago
    Total: 165s
    #131509
  • Pipeline finished with Success
    10 months ago
    Total: 225s
    #131515
  • Pipeline finished with Success
    10 months ago
    Total: 162s
    #131588
  • Pipeline finished with Success
    10 months ago
    Total: 177s
    #131593
  • Pipeline finished with Success
    10 months ago
    Total: 166s
    #131596
  • Pipeline finished with Success
    10 months ago
    Total: 231s
    #131606
  • Pipeline finished with Canceled
    10 months ago
    Total: 40s
    #131713
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ
  • Pipeline finished with Failed
    10 months ago
    Total: 206s
    #131716
  • Pipeline finished with Success
    10 months ago
    Total: 250s
    #131721
  • Pipeline finished with Failed
    10 months ago
    Total: 208s
    #131785
  • Pipeline finished with Failed
    10 months ago
    #131866
  • Pipeline finished with Canceled
    10 months ago
    Total: 123s
    #131876
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    @pwolanin has some fantastic feedback on JWT security resulting the XOR operation to encrypt the sid in each JWT with a random pad.

  • Pipeline finished with Failed
    10 months ago
    Total: 177s
    #131880
  • Pipeline finished with Success
    10 months ago
    Total: 205s
    #131886
  • Pipeline finished with Failed
    10 months ago
    Total: 176s
    #131896
  • Pipeline finished with Success
    10 months ago
    Total: 176s
    #131908
  • Pipeline finished with Success
    10 months ago
    Total: 290s
    #131956
  • Pipeline finished with Success
    10 months ago
    Total: 178s
    #137161
  • Pipeline finished with Success
    10 months ago
    Total: 178s
    #137162
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    This still needs to stay as a 10.2 only project in order to benefit from the lazy service injection into the middleware.

  • πŸ‡ΊπŸ‡ΈUnited States mradcliffe USA

    Closed πŸ› Log out of user seems not to work. Closed: duplicate as duplicate of this issue and added it to the related issues. @ro-no-lo create that issue and @pwolanin had some discussion on it.

    I tested the patch recently on a local development site I am using as an API backend for front-end development training, and it works as intended when I call the logout request via an Angular app.

  • πŸ‡©πŸ‡ͺGermany ro-no-lo

    I copy and pasted the code from the !13 into my project.

    I tested with Postman if I can logout without sending the session cookie all along and it still does not work for me. To be honest I have no idea how I could help, because I only use JWT and was not going to fully understand the encoding of it and sorts. All I see is, that when I try to logout via Postman the Drupal side will fail.

    I debuged it to see what will happen. The decoding of the JWT will happen as expected and I see that a uid (payload/drupal/uid) is present. payload/iat and payload/exp are also present. $pad_id = $jwt->getClaim(['drupal', 'pad_id']); returns null and after that everything further down the line will return null or similar. So no session_id is obtained.

    Do I need to enable something to make it work?

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    @ro-no-lo did you enable the new module - jwt_sessions?

  • Heyyy, in general module works fine, but i have a trouble after logout.
    After logout i still can update entities with old jwt token (So i suppose that this token not was destroyed)

    I suppose that is an issue similar to ro-no-lo.

    Some person he was solved that issue or not yet ?

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    @quak this situation is tested for by the added tests. Made another jwt module is getting the way. Can you list all the modules with jwt_* installed on your site? Thanks!

  • πŸ‡©πŸ‡ͺGermany ro-no-lo

    T gave the jwt_sessions module another try, but I was wondering why it never worked in my case. I noticed that the EventSubscriber which shall create the "pad_id", never gets called. Thus the auto wiring from the jwt_session.yml seem not to work properly. I tried to rewrite the ...services.yml, but I have no idea what I can do about these bunch of closures in the constructor. Thus I gave up again.

  • πŸ‡©πŸ‡ͺGermany ro-no-lo

    I have trouble understand the logic here. Maybe it's some kind of priority thing, but nothing seem to work as exprected.

    My goal is to use JWT for auth (which works, except for the logout) and for downloading protected files. There is a jwt_path_auth module, which I have enabled, but just adding the jwt as query param never results in a success. When I step through the code with a debugger, the JwtSession comes first and will fail to find an Authentication or JWT-Authentication header, because it is just a like (maybe from an E-Mail). After that, the JWTPathAuto will fail to get the Claims (both) and everything after that fails also.

    The Session set Claim is correctly executed, when the login happens, but it seem not to matter later in the process.

  • πŸ‡ΊπŸ‡ΈUnited States pwolanin

    @ro-no-lo sounds like you have more of a support request - maybe try Slack?

    We are using the JWT path auth in production for accessing private files, so I assure you that it can work.

Production build 0.71.5 2024