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
Invalid token - state
does not match
#655
Comments
Can you reproduce this in any way? Your code looks fine, but we need to find a way to reproduce the issue. |
I'm having the same issue, happens of everly login, but on refresh, i can get profiles without issue. Here's my auth component: import Auth0Lock from 'auth0-lock';
import { withRouter } from 'react-router-dom';
import { Component } from 'react';
import PropTypes from 'prop-types';
class AuthProvider extends Component {
static propTypes = {
history: PropTypes.object.isRequired, // eslint-disable-line
children: PropTypes.func.isRequired,
};
constructor(props) {
super(props);
this.state = {
profile: null,
};
this.history = props.history;
this.lock = new Auth0Lock(AUTH_CONFIG.clientId, AUTH_CONFIG.domain, {
autoclose: true,
auth: {
redirectUrl: AUTH_CONFIG.callbackURL,
responseType: 'token id_token',
audience: `https://${AUTH_CONFIG.domain}/userinfo`,
params: {
scope: 'openid profile',
},
},
});
this.handleAuthentication();
// binds functions to keep this context
this.getProfile = this.getProfile.bind(this);
}
componentWillMount() {
const { userProfile, getProfile } = this;
if (!userProfile) {
getProfile((err, profile) => {
this.setState(state => ({
...state,
profile,
}));
});
} else {
this.setState(state => ({
...state,
profile: userProfile,
}));
}
}
getProfile(cb) {
const accessToken = this.getAccessToken();
if (accessToken) {
this.lock.getUserInfo(accessToken, (err, profile) => {
if (profile) {
this.userProfile = profile;
}
cb(err, profile);
});
}
}
getAccessToken = () => {
const accessToken = localStorage.getItem('accessToken');
if (!accessToken) {
console.error('No access token found');
}
return accessToken;
}
setSession(authResult) {
if (authResult && authResult.accessToken && authResult.idToken) {
// Set the time that the access token will expire at
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
localStorage.setItem('accessToken', authResult.accessToken);
localStorage.setItem('idToken', authResult.idToken);
localStorage.setItem('expiresAt', expiresAt);
// navigate to the home route
this.history.replace('/');
}
}
handleAuthentication() {
// Add a callback for Lock's `authenticated` event
this.lock.on('authenticated', this.setSession.bind(this));
// Add a callback for Lock's `authorization_error` event
this.lock.on('authorization_error', (err) => {
console.log(err); // eslint-disable-line no-console
this.props.history.replace('/');
});
}
isAuthenticated = () => {
// Check whether the current time is past the
// access token's expiry time
const expiresAt = JSON.parse(localStorage.getItem('expiresAt'));
return new Date().getTime() < expiresAt;
}
login = () => {
// Call the show method to display the widget.
this.lock.show();
}
logout = () => {
// Clear access token and ID token from local storage
localStorage.removeItem('accessToken');
localStorage.removeItem('idToken');
localStorage.removeItem('expiresAt');
// navigate to the home route
this.props.history.replace('/');
this.setState(() => ({
profile: null,
}));
}
render() {
const { children } = this.props;
return children({
profile: this.state.profile,
authInstance: this.lock,
login: this.login,
logout: this.logout,
authenticated: this.isAuthenticated(),
});
}
}
export default withRouter(AuthProvider); and login: import React from 'react';
import Button from 'components/button';
import Auth from 'components/auth';
import { withRouter } from 'react-router-dom';
const LoginPage = () => (
<div>
<Auth>
{({
login,
}) => (
<button
onClick={login}
className="
Bd(n)
Bg(n)
"
>
<Button>
Log In
</Button>
</button>
)}
</Auth>
</div>
);
export default withRouter(LoginPage); |
thanks @VinSpee can you build a simple repro so we can isolate the issue? |
I've seen this happening sometimes if the authorize request is made from a different origin than the callback URL. E.g. you navigate to "http://myapp.com", and instead of redirecting first to "https://myapp.com", it goes directly to "https://yourtenant.auth0.com/authorize?...&redirect_uri=https://myapp.com" (notice the difference between "http://" and "https://"). @luisrudge for easier troubleshooting, I might be a good idea to log in the console a little more data, like the state that came in the callback, and what was there in localStorage (no match?). Even a list of states present in LocalStorage might help. Or maybe just handle one possible state storage slot instead (i.e. not including the |
@nicosabena that's a nice idea, but always logging that would not be good. Maybe we should have a debug mode (manually set localStorage or ?debug in the url or something). |
Here's a minimal repro: code: https://github.com/VinSpee/auth0-debug |
@VinSpee are you having this issue with google apps only? |
@luisrudge to be more clear: I am able to get the profile, but always get the console error:
|
@VinSpee ah, right. Sorry I missed that! Does this happen only with google? |
i've only tried in w/ google auth, I'll try with another provider |
I just tried it w/ GitHub as the provider and got the same error:
|
@VinSpee your code is running twice: Every time you use the So, it runs twice because you use the component both in the index route and in child routes: We have a react sample here if you want to take a look. You're also shipping two versions of react, because auth0-lock is using react@15, so you need to add this to your package.json file: "resolutions": {
"react": "^16.2.0",
"react-dom": "^16.2.0"
} |
I've been having the same problem, and I've found a workaround which I'll describe below just because I saw a lot of google results for this error, which seemed to be caused by all kinds of different things. However, I did find the proper solution, which is to use
My problem was that I generated a logout url using
When someone hits the site and isn't authenticated, I redirect them to auth0 with
|
@staab not sure I understand: why are you setting a state when doing a log out? |
@luisrudge because I'm redirecting to the login page for auth0, which doubles as our landing page for folks who aren't signed in (I'm not using auth0-lock, and our software is login-only). As I understand it, there's no way to go to that page and have it successfully log someone in if |
to log in with the universal login page, you do: var options = {}; //anything you want, state is not required but you can use your own state here if you want
webAuth.authorize(options); to log out from auth0, you do: var options = {}; //again, no state required
webAuth.logout(options); I mean, you're free to call the /v2/logout endpoint by yourself (although I don't see the point in doing it manually), but there's no need to send a state to the logout endpoint. |
@luisrudge that's what I'm doing now (see the top of my original comment). I was mostly including my manual logout solution for posterity, since I hadn't seen the mistake I had made anywhere else after some googling. After some more digging, it turns out that it's not logout that's passing |
Ok, so I tried passing a |
logout({
returnTo: 'https://myapp.com/login'
}) |
Ah ok thanks, that did the trick. Now that my credibility has been destroyed by not being able to read the documentation properly, is redirecting to the login page straight from the logout endpoint a common use case or am I an outlier? If it's common, it would be really nice for logout/buildAuthorizeUrl to handle setting |
from logout directly to the universal hosted login page is the first time I saw it 😝 your app > click logout > So, you create a step in between the logout and redirecting to the universal login page and, in this new step, you call authorize(). Then auth0.js will handle all the state and everything should work! |
Fair enough! I had it set up the way you described before, but I figured saving a redirect to my tool would be the best use of our resources and user experience. Not a big deal in any event though. Thanks for the help! |
I have come upon this error due to failure to JSON.stringify my state parameters before sending them to auth0 for authorize. Rather annoying error for a simple mistake. Auth0 library should really verify that the state is a "string" as objects don't work so well. |
@bramski what was the error? we want to support objects so you can restore an app state if you need to |
@luisrudge Here's the problem: |
same error as @VinSpee .But it works fine with google chrome .In mozilla,Error showing only in the first time of login and after the cookie added it works. |
do you mean the source code? |
I mean try to isolate the authentication code and make it fail so I can take a look or give me instructions on how to login in your application |
I can give you instructions on how to login, I'll send you an email in luis@luisrudge.net with credentials. Ok? |
before doing that, please send a HAR file with all the authentication requests to luis.rudge@auth0.com |
ok |
Also having this issue, Firefox 67 on linux. Using the ReactJS demo app, untouched |
This is still happening in the sample app, @luisrudge. You mentioned redirecting it to that team, could you provide a link so I can follow that issue? |
Can a trailing slash make a difference? f.e. And how does auth0 detect which location the app started at? |
@luisrudge Not sure I understand correctly. So for example, if we're on |
In all sincerity, this |
I think I'm using auth0-lock like normal. I've constructed it, and given it some options. Then when I try to log in, I call After stepping through auth0 code, I see that
But, I'm not calling What can be causing the Lock to indirectly cause that |
Yep, I can confirm by stepping through |
CRAAAAAP. So I'm using Note, in the However, now that I've solved that problem, and I can verify that
It'd be very nice for the Auth0 team to take this problem seriously and make it more clear, both in the documentation, and by providing contextual error messages rather than Now I'll continue to step through auth0 code in Chrome devtools until I find the second source of the error, which as paying customer wish I didn't have to do. If anything, a prorated refund of the wasted time would be very welcome, and would make all frustrations go away, because I need to be working on the business product where I work, instead of wasting resources. |
If you want to redirect to
I agree, but auth0-js doesn't have enough information on why the state didn't match. We can add the possible causes that we mentioned in this thread, but we can't pin point exactly what happened because there's simply not enough info. From Auth0-js's perspective, all we know is that we were expecting a string to be present in a cookie, but the string is not there.
I opened a PR to make it clearer that you can only use
See me previous message about not having enough context to pinpoint the issue
Feel free to ping our amazing support team at http://support.auth0.com to get some help figuring out your issue.
I can't do that, but feel free to ping someone at http://support.auth0.com with your frustrations to see what they can do. |
Thanks, I left a comment in the PR, I do think mentioning the exact Alright, I've found that inside of Any idea why |
Docs say:
I'm not supplying a |
@trusktr it is, unless you're using IE10 (no support to crypto) |
I'm in Electron with Chrome 66.0.3359.181. |
Looks like the |
FYI, Auth0.js and Lock do not support Electron. More context here. We have some guidance on how to build electron apps with Auth0 here: https://auth0.com/blog/securing-electron-applications-with-openid-connect-and-oauth-2/ |
Still, any idea why |
Here's another question: if we manually supply a |
Okay, even if I supply a hard-coded value for Note, every time I start the app, I've cleared all cache (deleted the Chrome profile and Electron folder). So it's completely clean. There's nothing in local storage, etc. |
I see I see Am I calling |
If |
@trusktr do you want to publish a repro somewhere that I can take a look? I feel like you're trying to dig into the internals too much and this feature is working as expected, so it should be an integration issue |
So for some reason I can't seem to authenticate users on certain computers/laptops that has the same browser versions.
auth.js
Login.vue
Picture:
Other details:
Auth0 version:
NPM -
8.12.2
ScriptJS -
8.12.2
Browser: Chrome Version 64.0.3282.140 (Official Build) (64-bit)
O.S: Windows 10
The issue is not happening on my laptop (which is running on the the Browser version mentioned above), but it is happening on other laptops (same browser version).
Not too sure what else to try here. Been looking at the forums, nothing is working out.
Would love some insights on this.
Thank you.
The text was updated successfully, but these errors were encountered: