Skip to content

Sessiontoken renewal #7248

Closed
Closed

Description

@FunnyDevs

New Feature / Enhancement Checklist

Current Limitation

Parse hasn't a strategy to renew a session token after it expires: so the user, to authenticate itself, must insert the credential agains. This is a big limitation in mobile applications.

Originally discussed in the community forum.

Feature / Enhancement Description

Add endpoint to renew the session token expire time together with new configuration parameters to define the renewal strategy

Activity

  1. jjunineuro commented on Mar 8, 2021

    @jjunineuro

    @mtrezza, I will reference here and close the topic that opens so as not to become a duplicate topic.

    Implement OAuth 2.0 as another Parser Server login option

  2. FunnyDevs commented on Mar 8, 2021

    @FunnyDevs
    Author

    @dblythy According to avoid long life token, there are two main reasons:

    1. Security: if someone intercepts the token, he can use it to authenticate to the server. With short life token (with a refresh token) if someone intercepts the token he can use it only for a very short period (the token duration); if he is able to intercept even the refreshtoken, he can use it to refresh the token only 1 time because both the sessiontoken both the refreshtoken change at every refresh token action.

    2. Better UX on mobile applications: every famous app (twitter,facebook,instagram...etc) use short life token together with refresh token, otherside they should show you login page after the token expiration time.

  3. jjunineuro commented on Mar 8, 2021

    @jjunineuro

    @dblythy exactly the OAuth 2.0 proposal, as you mentioned:

    Better UX on mobile applications: every famous app (twitter,facebook,instagram...etc) use short life token together with refresh token, otherside they should show you login page after the token expiration time.

  4. dblythy commented on Mar 8, 2021

    @dblythy
    Member

    Thanks for the detail in explaining this. I'd figure it would lead to greater discussion if we're all clear on the pros and cons of this implementation.

    So if I understand correctly:

    Current:

    • Session tokens will expire 1 year after the login, meaning that after one year users will be forced to re-login
    • If the session token is leaked, it can be used for the whole year by a malicious user

    With Oauth2.0:

    • Access tokens expire much sooner (e.g 30 days), but are "refreshed" when this happens, meaning that the users won't be forced to re-login
    • If the access token is leaked, it can only be used until the

    If that's the case, I'm in favour of adding the option for using OAuth, where Parse developers can opt in to allowing it in their configuration. Then, I'd expect that:

    • Old "session tokens" will still work until their expiry
    • New logins will use the newer "access token" and refresh system
    • Opting in would depend that the SDKs associated support "access token" (e.g, if the Flutter SDK doesn't support Oauth, a Flutter Dev wouldn't opt in to Oauth on their Parse Server)

    I'm not overly familiar with OAuth2.0 but as you've explained it, it seems to be a welcome improvement on the current auth system.

  5. jjunineuro commented on Mar 8, 2021

    @jjunineuro

    @dblythy a primary outline follows.
    Untitled Document

    Please read this introductory document on what is the JWT

    The idea is not to change the structure of the current Parse Server, but to implement the OAuth 2.0 rules.

    So, even if the choice is to use "oauth", Parse will continue to work with "sessions", it will only generate accessToken to allow access, as follows.

    accesstoken

    In the verification mechanisms when reading the header "X-Parse-Session-Token" (with "oauth" enabled) the SDK's instead of passing the sessionToken will pass the accessToken.

    1. Parse Server will validate that the accessToken is valid and is not expired and will retrieve the "sub" attribute that is simply the sessionToken.

    2. It will return the existing routine. And the request will be authenticated.

    Important points:

    1. When using "oauth", set the time if "sessionLength" to extreme values, eg 50 years

    2. The refreshToken will be saved in a new column in the "_Sessions" class and will be generated automatically using pseudo bytes with SHA-256 keys.

    3. The logout method when removing the session, removes the refreshToken consequently maintaining integrity.

    4. SDK's must continue to keep accessToken, refreshToken safe.

    In my case I use Parse Server for iOS, Android and the Web.

    For the Web (if the request uses the X-Parse-Javascript-Key), I decline to send the refreshToken, due to the weakness in not securely maintaining the refreshToken.

    In mobile developments, iOS (keychain) I can safely store just like in Android (Keystore) the refreshToken.

  6. mtrezza commented on Mar 8, 2021

    @mtrezza
    Member

    Just to throw this in: a migration scenario would be interesting to consider. It is not unusual that online services require all users to sign-in in again when they make a major shift to a more secure auth mechanism that supersedes a former best practice mechanism.

  7. jjunineuro commented on Mar 8, 2021

    @jjunineuro

    keeping "oauth" (Parse Server Options) as default (oauth: false), nothing will change, the same function remains.

    @mtrezza if I understood correctly, the migration scenario would be how SDK's should respond in the case of authentication by OAuth?

  8. mtrezza commented on Mar 8, 2021

    @mtrezza
    Member

    Yes, I mentioned the migration just to be considered on a high level. I can imagine that there will be developers who are interested in using OAuth2 and would want to migrate. If it's just a switch in the options, then it only requires to read the docs and maybe adapt the app, but if it requires more, then this may be something to think about.

  9. jjunineuro commented on Mar 8, 2021

    @jjunineuro

    there will be a change for the SDK's, for the developer, it will only be necessary to set "oauth" = true.

    I will prepare a scope of the change that should be made for the SDK's. Thanks @mtrezza

  10. mtrezza commented on Mar 8, 2021

    @mtrezza
    Member

    Great!

    How does this play with the Auth Adapter overhaul in #7079? @Moumouls put quite some effort into this, but I'm not sure what the current state of the PR is, i.e. when it will be merged. It looks almost done.

  11. cbaker6 commented on Mar 9, 2021

    @cbaker6
    Contributor

    Speaking from the Parse-Swift SDK, the flow mentioned in #7248 (comment) seems straight-forward and can probably be done quickly.

    @jjunineuro question, you mentioned the client needs to check expiration time. This seems like it “may” be slightly problematic as it’s dependent on a local device clock as oppose to a centralized server clock. Meaning it’s hard to enforce a device stays on the same clock, even if it’s the originating clock. My guess here, if a local clock changes and thinks the accessToken expires early, there’s no issue as it will just refresh before the expiration time. If a client still thinks it’s 1B accessToken` is valid, when it’s really not, does the server state it’s expired? If so, this sounds like it’s dependent on 2 clocks, which is also problematic. Now, this might be mitigated if by checking for expiration time you mean “always check against the server clock” and not a local clock. Can you clarify how this would work?

  12. jjunineuro commented on Mar 9, 2021

    @jjunineuro

    Hello @cbaker6 , both the creation date and the expiration of the token are sent in timestamp, which I believe the time of the device with the time of the server should not interfere.

    In the previous scheme I was wrong to put the formatted date, but it will be sent in timestamp.

    What can be done is as follows, the SDK's will check the expiration time (timestamp) and check if it has already expired, if it is expired, request the renewal of the token, to obtain the new access.

    Token example:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJyOmFjOTBiZDYxMGY2ZWFlOTA1ZjIzZWU0OGM1Yjg2MjU5IiwiaWF0IjoxNjE1MzAwNDcxLCJleHAiOjE2MTUzMDA3NzF9.umGIfZtryFyA-6JHzWVb5KJoYpj6Y2bqC4LmsJu5ZTE

    image

    Return of the login / signup request:

    {
       "objectId": "PIW64IyKDS",
       "username": "mylogin",
       "email": "myaddress@email.com",
       "createdAt": "2021-03-07T10:22:55.602Z",
       "updatedAt": "2021-03-07T10:22:55.602Z",
       "ACL":{
          "*":{
             "read": true
          },
          "PIW64IyKDS":{
             "read": true,
             "write": true
          }
       },
       "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJyOmFjOTBiZDYxMGY2ZWFlOTA1ZjIzZWU0OGM1Yjg2MjU5IiwiaWF0IjoxNjE1MzAwNDcxLCJleHAiOjE2MTUzMDA3NzF9.WabWg5Jdux3NMXKLWPj_vQMofzF1BgrZhzZI1pLVA7o",
       "refreshToken": "9d78221ae718662e5b765183cce87011184a5c68370af2c3a0d7e12e46410c9b",
       "expires_in": 1615300771
    }
    

    I started the sketch, but it is not yet finished. I still have to elaborate the schema for the SDK´s as @mtrezza asked.

  13. cbaker6 commented on Mar 9, 2021

    @cbaker6
    Contributor

    the creation date and the expiration of the token are sent in timestamp, which I believe the time of the device with the time of the server should not interfere.

    If the timestamps and determining expiration is solely dependent on the local device, it opens up the attack surface for a malicious user as they can simply manipulate the local wall clock or never ask for a refresh token. If it's using both clocks (local and server), there's no way to guarantee these clocks are in sync, even if you are using a value to represent time like 1615300771. If you are using only 1 clock (the server clock like the current sessionToken implementation) you are okay, assuming the server isn't under control of the malicious user. Maybe the OAuth2 RFC has something in its documentation to address this? I'm not familiar with implementing OAuth, but I don't see them not addressing this issue.

  14. jjunineuro commented on Mar 9, 2021

    @jjunineuro

    The expiration timestamp is sent only to the device to check if the "accessToken" is still valid to find out whether to request the update.
    When submitting the request with "accessToken" Parse Server will validate the token, if it is changed, it becomes invalid, because the third part of the token is signed with the key "oauthKey" that will be included in the Parse Server options .
    Therefore, it is not possible to change any data in the token.

  15. 33 remaining items

  16. jjunineuro commented on Mar 10, 2021

    @jjunineuro

    An excellent idea, but in "../src/Config.js" I didn't find "securityCheck"

  17. mtrezza commented on Mar 10, 2021

    @mtrezza
    Member

    Sorry, it's actually called security, only been merged into master some minutes ago. Steaming fresh!

  18. jjunineuro commented on Mar 10, 2021

    @jjunineuro

    Committed with the suggested changes. @mtrezza and @dplewis

  19. jjunineuro commented on Mar 11, 2021

    @jjunineuro

    I just need to correct the commit tests I performed, it is failing in the new functions implemented. I don't really know how to implement the tests.

  20. lsmilek1 commented on Apr 28, 2021

    @lsmilek1
    Contributor

    Would this work also with multi-device (multiple sessions) users?

    Let's say user sign in with Apple or Username/Password on two devices and get two sessions. Then he eventually stop using one, where the session should expire and on the other the should be silently able to renew the session. Or on the other hand he should be able to renew tokens on each sessions without affecting other sessions.

    Any idea when this could be released? Thank you!

  21. added
    type:featureNew feature or improvement of existing feature
    and removed on Dec 6, 2021
  22. parseplatformorg commented on May 17, 2023

    @parseplatformorg
    Contributor

    🎉 This change has been released in version 6.1.0-alpha.11

  23. parseplatformorg commented on Jun 10, 2023

    @parseplatformorg
    Contributor

    🎉 This change has been released in version 6.3.0-beta.1

  24. parseplatformorg commented on Jun 18, 2023

    @parseplatformorg
    Contributor

    🎉 This change has been released in version 6.3.0-alpha.1

  25. parseplatformorg commented on Sep 16, 2023

    @parseplatformorg
    Contributor

    🎉 This change has been released in version 6.3.0

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions