-
Notifications
You must be signed in to change notification settings - Fork 9
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
Token refresh/renewal #7
Comments
i was thinking I could have the client "ping" a refresh/renew function periodically as part of the user's activity on the site, not while they are idle. This function would:
I've never created a postgresql stored procedure/function but it seems like the pieces are there. I may take a crack at it if I'm feeling brave. |
Something like this maybe?
This seems to work. I just don't know how to handle it when the token isn't valid. Maybe the client does the right thing depending on the value returned for |
This probably isn't the best approach. Should incorporate a refresh token and return a "user" object just like |
I think I got it:
|
How is this coming along for you? Ready to get started and want to lock in my auth strategy before anything else. Any adjustments or lessons learned? I assume you have a (good work, thanks for sharing) |
Another approach to take on this - You could create a refresh_token field in your user table: create table hasura_user(
id serial primary key,
email varchar unique,
crypt_password varchar,
cleartext_password varchar,
default_role varchar default 'user',
allowed_roles jsonb default '["user"]',
enabled boolean default true,
refresh_token text,
jwt_token text
); Then sign a Characteristics of refresh vs access tokens (jwt_token in this example) are that they're long vs short lived, and they don't have credentials (they're just used for refreshing the access token). For this example I created a 1 week refresh token and a 5 minute access token. I also hardcoded the roles as create or replace function hasura_auth(email in varchar, cleartext_password in varchar) returns setof hasura_user as $$
select
id,
email,
crypt_password,
cleartext_password,
default_role,
allowed_roles,
enabled,
sign(
json_build_object(
'sub', id::text,
'iss', 'Hasura-JWT-Auth',
'iat', round(extract(epoch from now())),
'exp', round(extract(epoch from now() + interval '168 hour')),
'https://hasura.io/jwt/claims', json_build_object(
'x-hasura-user-id', id::text,
'x-hasura-default-role', 'anonymous',
'x-hasura-allowed-roles', ('["anonymous"]')::jsonb
)
), current_setting('hasura.jwt_secret_key')) as refresh_token,
sign(
json_build_object(
'sub', id::text,
'iss', 'Hasura-JWT-Auth',
'iat', round(extract(epoch from now())),
'exp', round(extract(epoch from now() + interval '5 minute')),
'https://hasura.io/jwt/claims', json_build_object(
'x-hasura-user-id', id::text,
'x-hasura-default-role', default_role,
'x-hasura-allowed-roles', allowed_roles
)
), current_setting('hasura.jwt_secret_key')) as jwt_token
from hasura_user h
where h.email = hasura_auth.email
and h.enabled
and h.crypt_password = hasura_encrypt_password(hasura_auth.cleartext_password, h.crypt_password);
$$ language 'sql' stable; I can then created a Use case: your access token (jwt_token) has expired. You come through the front-door of Hasura using your refresh token in the header. Hasura will validate the token, and use your Note: This isn't technically a refresh_token, since generally a refresh_token would just re-sign the current token with a new exp. Here, we're actually re-generating the token - which actually has its upsides since in this model you could check every 5 minutes to make sure the user is still enabled, and their claims are still valid. create or replace function hasura_refresh(hasura_session json) returns setof hasura_user as $$
select
id,
email,
crypt_password,
cleartext_password,
default_role,
allowed_roles,
enabled,
'' as refresh_token,
sign(
json_build_object(
'sub', id::text,
'iss', 'Hasura-JWT-Auth',
'iat', round(extract(epoch from now())),
'exp', round(extract(epoch from now() + interval '5 minute')),
'https://hasura.io/jwt/claims', json_build_object(
'x-hasura-user-id', id::text,
'x-hasura-default-role', default_role,
'x-hasura-allowed-roles', allowed_roles
)
), current_setting('hasura.jwt_secret_key')) as jwt_token
from hasura_user h
where h.id = (hasura_session ->> 'x-hasura-user-id')::int
and h.enabled
$$ language 'sql' stable; After we've tracked everything - our request (anonymous header): query authLogin {
hasura_auth(args: {email: "your_email", cleartext_password: "your_password"}) {
jwt_token
refresh_token
}
} And our refresh request (refresh_token authorization header): query refreshToken {
hasura_refresh {
jwt_token
}
} |
Have you considered how token refresh/renewal might work using this setup?
As long as the user is actively using the system it would be ideal if they could continue to do so without having to re-auth.
Just looking for ideas if you've got them.
BTW, I have this setup running in a limited release production environment!
The text was updated successfully, but these errors were encountered: