workos / workos-python

Official Python SDK for interacting with the WorkOS API
https://workos.com/docs/sdk/python
MIT License
47 stars 11 forks source link

Status of AuthKit #350

Open hyperknot opened 2 months ago

hyperknot commented 2 months ago

Either in this repo, or on the Flask sample, what is the status of AuthKit integration?

I've been manually translating the node examples into Python, here is what I've come up with for the core parts.

I looked into the state of JWT in Python and the most up-to-date library currently is joserfc.

These are snippets for LiteStar framework, but the core parts should be extracted probably into the SDK, so not everyone has to look up the right JWKS validation libraries and methods.

from joserfc import jwt
from joserfc.jwk import KeySet
def get_jwks():
    jwks_url = client.user_management.get_jwks_url()

    r = requests.get(jwks_url)
    config.workos_key_set = KeySet.import_key_set(r.json())
def check_session(connection: ASGIConnection) -> bool:
    """returns True if success, False if login is needed"""

    session = connection.session

    access_token_exp = session.get('access_token_exp')
    if access_token_exp and time.time() < access_token_exp:
        return True

    # get new access token using refresh token
    try:
        workos_data = client.user_management.authenticate_with_refresh_token(
            refresh_token=session.get('refresh_token')
        )
        update_session(connection, workos_data)
        return True
    except Exception:
        return False

def update_session(connection: ASGIConnection, workos_data) -> bool:
    """returns True if success, False if login is needed"""

    try:
        claims_requests = jwt.JWTClaimsRegistry()
        claims = jwt.decode(workos_data['access_token'], config.workos_key_set).claims
        claims_requests.validate(claims)
    except Exception:
        return False

    new_session = connection.session | {
        'access_token_exp': claims['exp'],
        'session_id': claims['sid'],
        'refresh_token': workos_data['refresh_token'],
    }

    if user := workos_data.get('user'):
        new_session['user'] = user

    connection.set_session(new_session)
    return True
PaulAsjes commented 2 months ago

This is actually very timely, we recently released session helper methods for the Node SDK (which you can see in the AuthKit quick start) which we're now in the process of porting to other languages, including Python.

Thanks for this, it helps knowing which JWT is the most popular in Python world.

Once those helper methods land in the Python SDK I'll let you know in this issue.

hyperknot commented 2 months ago

Thanks a lot for letting me know! Also, once the official implementation is done, please let me know if there is a logic error in my code.