Angular 4 application running in browser (website backend), displaying from the server data owned by particular user. Server: PHP+MySQL, Zend Framework 3 + Doctrine ORM
Naming:
access_token
: Short lifetime (1 min), allows to access personal resources, carries user_id, base64 encoded, json web token spec valid.refresh_token
: Long lifetime (1 week) allows to retrieve new access_token without providing credentials, stored in db, can be revoked by admin if needed.Main point of using refresh_tokens is to be logged in longer than access_token
short lifetime (possibly forever if refresh_token
expiration time is updated each time user authorization happens), user needs to provide credentials only in case of inactivity longer than refresh_token
lifetime.
Refresh tokens are stored in db, so can be easily revoked.
REQUEST:
RESPONSE:
Username and password is validated and checked against database
If valid:
access_token
is generated with expiration time 60secuser_id
is encoded into access_tokenrefresh_token
is generated (random string) and saved to db, expiration time 1 week, (refresh_token is not included in access_token, it's a separate key)If invalid:
ACTION AFTER
IF valid:
refresh_token
stored in browser (private member varialbe of auth service, browser's local storage). Looks like it's not a good idea to store refresh_token
in local storage - but this allows for "keep me signed in". If stored only per browser session in private member variable, user would need to log in every time opens the browser. Any ideas?
If invalid:
REQUEST:
RESPONSE:
ACTION AFTER RESPONSE:
REQUEST:
RESPONSE:
access_token
(everything except expiration time, using \Firebase\JWT)refresh_token
against database (user_id decoded from access_token, the string and expiration time)If valid:
Generate new refresh_token, save to database, update ttl (or should be the same token, only updated ttl?) Generate new access_token HTTP 200 OK
If invalid:
HTTP 401 Unauthorized
ACTIONS AFTER RESPONSE:
If valid:
If invalid:
The key point I don't like is that access_token and refresh_token are stored in the same place and sent the same way. Maybe there is another way to do it?
refresh_token
be encoded in access_token
? If they are still saved in the same place, looks that it may be incorporated into access_token. Any reasons not to do it?refresh_token
lifetime?Regarding where to store tokens and the security flaws (taken from Github user brettpostin https://github.com/IdentityServer/IdentityServer3/issues/2039#issuecomment-288135399) keep in mind that:
Best option is to protect against both as described here: http://www.redotheweb.com/2015/11/09/api-security.html
Store your tokens in http-only cookies and use a suitable targeted csrf defense as suggested here: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
when should I update refresh_token lifetime?
If you are asking when to update the refresh token it depends on the implementation of your protocol, for example Google Auth server issued Refresh tokens never expire, they are revoked when the user revokes access to the app. But may I suggest a few weeks, so you don't lose control over it.
any open source projects to see similar authentication in action?
Well, you can download any project that uses OAuth2, for example this project on github: https://github.com/authlib/example-oauth2-server
any other suggestions?
Have a look at OpenID Connect and Identity Providers (IDPs) such as Keycloack.
Hope this helps you in any way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With