Hi, after the weekend, my website on the localhost started requesting “*** Client is requesting access to your dev-*** account", and it stopped saving the session and started asking to log in on every page reload.
What is checked:
- The production environment is working as expected.
- Authorization configuration was not changed on my side, not in the codebase, not in the dashboard.
audience is matched on both sides, in local configuration and in the dashboard.
- "
Allow Skipping User Consent" It is turned on in the dev environment dashboard.
I expect it not to ask for consent and the session to be saved without login on every page reload.
It was working perfectly fine for more than a year until today.
Does anybody know how to fix this issue?
Hi @yaroslavtereshchuk
Welcome back to the Auth0 Community!
The root cause of this sudden change could be your web browser. Over the weekend, your browser likely received an update that enabled strict Third-Party Cookie Blocking .
This browser update breaks the hidden iframe mechanism Auth0 uses to silently restore your session on localhost . Because the silent session restoration fails, your app forces a full, interactive login on every reload. The consent screen is appearing because Auth0 has a hardcoded security rule: applications running on localhost are never allowed to silently skip user consent.
Please try the following things and let me know if they work for you or not:
-
In Chrome: Navigate to chrome://settings/trackingProtection (or chrome://settings/cookies ) and either disable tracking protection temporarily or add [*.]auth0.com to the list of sites allowed to use third-party cookies.
-
Since third-party cookies are going away permanently across all browsers, the modern best practice is to stop relying on the hidden iframe entirely by using Refresh Token Rotation.
- In your Auth0 Dashboard, go to your Application settings and enable Refresh Token Rotation .
- In your SPA codebase (if using
@auth0/auth0-react or @auth0/auth0-spa-js ), update your Auth0Provider/Client configuration to include:
useRefreshTokens: true,
cacheLocation: 'localstorage'
This allows the SDK to save a rotating refresh token in your browser’s local storage, surviving page reloads without ever needing to rely on third-party cookies.
- If you implement Refresh Tokens but still want to eliminate the consent screen on your very first local login, you must stop using
localhost .
If you have any other questions, let me know!
Kind Regards,
Nik
Thank you for the answer.
What I did:
- I added
[*.]auth0.com to the list of allowed sites to use third-party cookies.
- Checked
Refresh Token Rotation and it is enabled.
- Added
useRefreshTokens and cacheLocation params to the configuration on the implementation side.
What is the result:
- Site stopped asking for login on every page reload.
- But the “Consent” window is still showing.
My current questions:
- Can I remove the “Consent” window on the localhost?
- Isn’t storing tokens in
localstorage vulnerable? If someone tricks the user into pasting a malicious script in the console, the user’s token can be stolen. Or is this configuration only for the development environment?
We are having the same issue with localhost. All bullet points from the first message apply to us as well.
Localhost was working fine last week, but silent authentication started failing yesterday, and we’re not sure why.
The error we see in the logs is:
"error": {
"message": "Consent required",
"oauthError": "consent_required",
"type": "oauth-authorization"
},
We suspect this may be related to how the browser handles third-party cookies, but we haven’t been able to confirm this theory in the browser settings.
We purposely avoided using Refresh Token Rotation due to security concerns.
Hi again!
The consent screen is being forced by Auth0 whenever the application is being run on a localhost environment.
If you implement Refresh Tokens but still want to eliminate the consent screen on your very first local login, you must stop using localhost.
- [A Recommended Workaround]:
- Edit your computer’s
hosts file (e.g., /etc/hosts on Mac/Linux, C:\Windows\System32\drivers\etc\hosts on Windows).
- Add a custom mapping:
127.0.0.1 mylocalapp.com
- In your Auth0 Dashboard, replace
http://localhost:3000 with http://mylocalapp.com:3000 in your Allowed Callbacks, Web Origins, and CORS settings.
- Run your local dev server and navigate to
http://mylocalapp.com:3000 . Because it is no longer localhost , Auth0 will respect the “Allow Skipping User Consent” toggle.
Alternatively, you can try searching for and use some other methods to stop hosting the application on a localhost url which could be better suited for your use case.
In order to answer you second question, storing tokens in localstorage is vulnerable to Cross-Site Scripting (XSS) attacks. Any JavaScript running on the page—whether from a malicious browser extension, a compromised NPM package, or a user pasting a script into the console (Self-XSS)—can read localstorage .
However, this configuration is only for development in your specific case. Otherwise, It is widely used in production today as a necessary architectural tradeoff, but it is only considered secure when strictly paired with Auth0’s Refresh Token Rotation (RTR) mechanism.
As I have mentioned above @eriks1, the consent_required error on localhost during silent authentication is an intentional security feature by Auth0. Auth0 considers localhost an unverifiable domain, so it always forces a user consent screen, ignoring any “Allow Skipping User Consent” toggles.
Most probably, It worked for you last week because you had an active session cookie established from an initial login, and your browser allowed third-party cookies for the silent iframe. If it broke yesterday, your initial session expired, or your browser finally enforced its third-party cookie blocking policy, preventing the iframe from reading that session and forcing Auth0 to re-evaluate the consent rules for localhost .
To remediate this issue, you can follow the provided workaround or you must adjust your frontend code to expect this failure. When getAccessTokenSilently() throws a consent_required (or login_required ) error, you must seamlessly fallback to an interactive login method so the user can actually see and click the consent screen.
Kind Regards,
Nik
Hi, thank you for the answer.
Now I have enough information about what to expect and how to deal with the issue.