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

Refresh Tokens #34

Closed
clusby opened this Issue Nov 19, 2017 · 3 comments

Comments

Projects
None yet
3 participants
@clusby
Copy link

clusby commented Nov 19, 2017

I appreciate the work on this project.

Currently any expired access token can be used along with the refresh token, to gain a new access token.

Instead would it make sense to represent the refresh_token as a JWT itself, such that:

  • The user info can be added into the token, instead of having to use an unverified access token.
  • We can add an expiry time to the refresh token (currently lasts forever, unless the application code adds TTL logic in it's store).

Thanks

@ahopkins

This comment has been minimized.

Copy link
Owner

ahopkins commented Dec 6, 2017

I feel like the refresh token should be handled by application logic. Perhaps there may be a need to add a MAX_EXPIRATION time so that any access token that exceeds the maximum cannot be used to refresh.

This is sort of why retrieve_refresh_token exists. To allow the user control.

Perhaps get_refresh_token becomes a handler method like extend_payload that can be easily overwritten by the user that may want a more robust refresh token.

I'm on the fence about this one and would like to hear more input from anyone that has thoughts.

@ahopkins

This comment has been minimized.

Copy link
Owner

ahopkins commented Feb 12, 2018

I am closing this. While the idea seems good, I think it is a use case that the core implementation is not going to support. However, if someone would like to achieve this functionality, it will be available in version 1.0.

from sanic import Sanic
from sanic_jwt import Initialize, Authentication
from datetime import datetime, timedelta


class MyAuthentication(Authentication):
    async def get_refresh_token(self, request, user):
        payload = {
            'exp': (datetime.now() + timedelta(days=2)).timestamp()
        }
        algorithm = self._get_algorithm()
        refresh_token = jwt.encode(payload, secret, algorithm=algorithm)
        user_id = await self._get_user_id(user)
        await utils.call(
            self.store_refresh_token,
            user_id=user_id,
            refresh_token=refresh_token,
            request=request)
        return refresh_token

class MyInitialize(Initialize):
    authentication_class = MyAuthentication

async def check_and_retrieve_refresh_token(request, *args, **kwargs):
    user = request.app.auth.retrieve_user(request, **kwargs)
    refresh_token = some_method_to_get_refresh_token(user)
    if datetime.now().timestamp() > refresh_token.get('exp'):
        return None
    return refresh_token

app = Sanic()

MyInitialize(app, authenticate=lambda: True, retrieve_refresh_token=check_and_retrieve_refresh_token)

@ahopkins ahopkins closed this Feb 12, 2018

@vltr

This comment has been minimized.

Copy link
Collaborator

vltr commented Feb 13, 2018

This looks good. Nice! 😄

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