Storing Refresh Tokens
When you're using Descope on the client-side, it's imperative that you store your refresh tokens securely. Your refresh tokens are typically valid for 1 month, and if they are exposed, attacks can create their own session tokens to authenticate as someone else, effectively as if they had stolen their password.
Luckily Descope has many standards in place to prevent this from happening and
The refresh token expiry time should be decided based on the requirements of your application (tradeoff between higher security and user experience). A shorter expiration time means that the user will need to authenticate frequently.
If you are using Client SDK (including Flows), Descope manages the refresh token storage for your application client. Depending on the project configuration, the Descope service can return the refresh token in two different ways - "manage in cookies" and "manage in response body".
Handling Refresh Tokens in Cookies
It is recommended to store your refresh tokens in cookies, rather than in the browser localStorage. This is important because it will help mitigate the risk of XSS (Cross-site-scripting) attacks, since tokens in localStorage are accessible via JavaScript. Since Descope uses httpOnly
cookies, the refresh token will not be accessible using JavaScript. Descope cookies are also sameSite=strict
and protected against cross-site request forgery attacks. In the Console, under Token Response Method you can configure Descope to store your tokens in an httpOnly
cookie instead. In order to use cookies, you must provide a custom domain and configure a CNAME for this as well.
As a best practice, make sure to limit your custom domain scope as much as possible. This more specific scope will limit the number of places your browser will send the cookie. If your cookie only needs to be sent with requests using the domain "app.company.com", then your scope should be that rather than the entire website "company.com".
Note
If you are using cookies to store the refresh token, you might encounter a 401 Unauthorized
when testing your app locally since localhost
will differ from the custom domain you configure a CNAME
for. To handle this, it's recommended that you follow this guide to configure multiple descope developer environments.