Skip to content
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

"AuthStateMissing: Session value state missing" on logins with set session cookies #534

Closed
hibbie opened this issue Feb 24, 2015 · 39 comments

Comments

@hibbie
Copy link

hibbie commented Feb 24, 2015

I'm working to integrate Facebook and Google OAuth2 into a site that already has working login using contrib.auth. I'm now stuck with a situation where I will receive a AuthStateMissing for both Google-Oauth2 and Facebook. The only way to successfully log in with those services is to wipe out my site cookie prior to clicking login. If I do that I can login once. Then if I try to login again I'll receive another AuthStateMissing. I've checked past issues and the site is on a subdomain of a TLD, the callback urls are correct.

The traceback:

Traceback (most recent call last):

  File "/home/env/tcm/lib/python3.4/site-packages/django/core/handlers/base.py", line 112, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)

  File "/home/env/tcm/lib/python3.4/site-packages/newrelic-2.42.0.35/newrelic/hooks/framework_django.py", line 497, in wrapper
    return wrapped(*args, **kwargs)

  File "/home/env/tcm/lib/python3.4/site-packages/django/views/decorators/cache.py", line 52, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)

  File "/home/env/tcm/lib/python3.4/site-packages/django/views/decorators/csrf.py", line 57, in wrapped_view
    return view_func(*args, **kwargs)

  File "/home/env/tcm/lib/python3.4/site-packages/social/apps/django_app/utils.py", line 52, in wrapper
    return func(request, backend, *args, **kwargs)

  File "/home/env/tcm/lib/python3.4/site-packages/social/apps/django_app/views.py", line 28, in complete
    redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)

  File "/home/env/tcm/lib/python3.4/site-packages/social/actions.py", line 40, in do_complete
    user = backend.complete(user=user, *args, **kwargs)

  File "/home/env/tcm/lib/python3.4/site-packages/social/backends/base.py", line 40, in complete
    return self.auth_complete(*args, **kwargs)

  File "/home/env/tcm/lib/python3.4/site-packages/social/backends/oauth.py", line 361, in auth_complete
    state = self.validate_state()

  File "/home/env/tcm/lib/python3.4/site-packages/social/backends/oauth.py", line 87, in validate_state
    raise AuthStateMissing(self, 'state')

social.exceptions.AuthStateMissing: Session value state missing.

My relevant settings:


INSTALLED_APPS = {
    'social.apps.django_app.default',
}
...
 AUTHENTICATION_BACKENDS = (
    'social.backends.facebook.FacebookOAuth2',
    'social.backends.google.GoogleOAuth2',
    'django.contrib.auth.backends.ModelBackend'
)
...
TEMPLATE_CONTEXT_PROCESSORS = (
   'django.contrib.auth.context_processors.auth',
   'django.core.context_processors.debug',
   'django.core.context_processors.i18n',
   'django.core.context_processors.media',
   'django.core.context_processors.static',
   'django.core.context_processors.tz',
   'django.contrib.messages.context_processors.messages',
   'social.apps.django_app.context_processors.backends',
   'social.apps.django_app.context_processors.login_redirect',
)

The errors only trigger once I am sent back to my site. So it doesn't appear to be related to either Google or Facebook.

@tark-hidden
Copy link

How to repeat:

  • Try to login with some auth provider
  • Remove session cookie (and you can to restart uwsgi, if you want)
  • Try to login again
  • Get 502 error

Same here with Pyramid framework.

@craig-hacklaunch
Copy link

This is also a problem if you are using a partial pipeline, for example during email validation. If the user tries to complete the sign up from a different device so the session is simply not available. Also if you have a partial pipeline and the user uses a second backend to login while the first is partially complete the partial for the first is removed. This mean if they come back later to to complete the validation through the email link it will no longer be valid.

@catskul
Copy link

catskul commented May 11, 2015

As far as I can tell every version post 0.2.0 has this problem. I tried upgrading to the latest and noticed this issue.

@marcussaad
Copy link

Having the same issue here when logging through mobile

@anzellai
Copy link

Any update on this? I have encountered this similar issue, and it raises AuthStateMissing: Session value state missing. both on Facebook and Twitter, it happens across different desktop/mobile devices (Windows/Mac/Android/iOS).
I am on version 0.2.11.

@ericson-cepeda
Copy link

It happened to me that trying to access with: http://localhost/complete/oauth2test?state=vkTqtm0 works, but: http://localhost/complete/oauth2test/?state=vkTqtm0EsOj8E5oTDg5bGMabIgl172A0 did not.

Once the trailing '/' (oauth2test/) was removed, the error disappeared.

@anzellai
Copy link

@ericson-cepeda, interesting and thanks for the tip 👍
I am using Django with it and have set to append the url with trailing slash to get other modules playing nice together, so it could well be the culprit like you suggested.
Will give it a go on Monday and provide updates.

@TeckFA
Copy link

TeckFA commented Jul 21, 2015

While debugging this adding traces to the server log, I noticed the following sequence of events WRT session state, during Google OAuth2 interactions. (Function names refer to oauth.py.) First, there is state:

get_or_create_state has state OiVSTFTN1O4CsnYNA72RZDP65QaTDAFm for google-oauth2_state

(The value is returned by self.strategy.session_get). Then there is a 302 /login/google-oauth2/, and after that, the session state value seems to have gone:

get_session_state returning None for google-oauth2_state

It is validate_state that calls get_session_state and then raises AuthStateMissing, since state is now gone, indeed. (Could it be that something is not flused to the session/db?)

FTR, earlier in the server log lines there are Python strings for SQL; they seem to lack quotes around the values to be compared (but I'm no expert in these ORM matters!),

... WHERE ("django_session"."session_key" = %s AND "django_session"."expire_date" > %s)

@anzellai
Copy link

@ericson-cepeda, by removing the trailing slash on provider/ like you suggested, I can confirm the same error hasn't come back since 👍

@TeckFA
Copy link

TeckFA commented Jul 24, 2015

FTR, there are TRAILING_SLASH (urls.py), and APPEND_SLASH (Django, in case). Maybe a stackoverflow discussion on redirects applies.

@pellaeon
Copy link

@TeckFA I hit the same problem, same sympton as you observed. Digging deeper, I found that cookies are NOT port specific , so if you run both OAuth client and provider on the same host, when being redirected to the provider to authenticate, it will overwrite the sessionid cookie set by the client, making client unable to retrieve the correct session object after being redirected back by the provider.

@ivictbor
Copy link

ivictbor commented Sep 7, 2016

@pellaeon OMG, thanks a lot!!! You saved my day!

@petrklus
Copy link

I am seeing the same issue on my side as well:

AuthStateMissing: Session value state missing.
  File "django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "django/views/decorators/cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "social/apps/django_app/utils.py", line 51, in wrapper
    return func(request, backend, *args, **kwargs)
  File "social/apps/django_app/views.py", line 28, in complete
    redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
  File "social/actions.py", line 44, in do_complete
    user = backend.complete(user=user, *args, **kwargs)
  File "social/backends/base.py", line 41, in complete
    return self.auth_complete(*args, **kwargs)
  File "social/utils.py", line 246, in wrapper
    return func(*args, **kwargs)
  File "social/backends/oauth.py", line 385, in auth_complete
    state = self.validate_state()
  File "social/backends/oauth.py", line 88, in validate_state
    raise AuthStateMissing(self, 'state')

I have tried disabling the trailing slash with the TRAILING_SLASH parameter but the result is the same.

@Pomax
Copy link

Pomax commented Nov 23, 2016

I am hitting this as well, but I don't know how to act on the information that @pellaeon provides: This is a single Django instance on a single machine, on the same port, so I have a "client" page on http://localhost:8000/pages that presents the user with a login link:

<a href="http://localhost:8000/auth/login/google-oauth2?next=%2Fauth%2Fcomplete%2Fgoogle-oauth2">click here</a>

I click this, and then run through the google auth process, where google redirects to:

http://localhost:8000 /auth/complete/google-oauth2/?state=...&code=...&authuser=0&hd=...&session_state=...&prompt=none HTTP/1.1

While the initial redirect clearly has a state value, that disappears somewhere:

Internal Server Error: /auth/complete/google-oauth2/
Traceback (most recent call last):
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
    response = get_response(request)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/social/apps/django_app/utils.py", line 51, in wrapper
    return func(request, backend, *args, **kwargs)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/social/apps/django_app/views.py", line 28, in complete
    redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/social/actions.py", line 44, in do_complete
    user = backend.complete(user=user, *args, **kwargs)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/social/backends/base.py", line 41, in complete
    return self.auth_complete(*args, **kwargs)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/social/utils.py", line 246, in wrapper
    return func(*args, **kwargs)
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/social/backends/oauth.py", line 385, in auth_complete
    state = self.validate_state()
  File "/Users/Pomax/Documents/git/temp/venv/lib/python2.7/site-packages/social/backends/oauth.py", line 86, in validate_state
    raise AuthMissingParameter(self, 'state')
AuthMissingParameter: Missing needed parameter state
[23/Nov/2016 21:37:44] "GET /auth/complete/google-oauth2/ HTTP/1.1" 500 98565

No amount of adding or removing trailing slashes seems to have any effect on this, and this happens every time, not intermittently

@omab
Copy link
Owner

omab commented Dec 27, 2016

There was an error that made state getting validated on error responses from the provider that masked the real error as an state-missing problem, this got fixed by python-social-auth/social-core@4d2903c

@omab omab closed this as completed Dec 27, 2016
@lisad
Copy link

lisad commented Jan 31, 2017

I just discovered that adding "SESSION_COOKIE_SECURE = True" can start this error happening. Obviously that's pilot error - me telling the site not to accept session cookies unless over HTTPS but trying to use HTTP anyway. But I imagine it would be hard to diagnose if I hadn't just changed just this one setting (in fact I came looking for a more complete answer anyway).

@dvdhpkns
Copy link

Thanks @lisad, this was my issue!

@Pomax
Copy link

Pomax commented Feb 20, 2017

@lisad is that a thing you might be able to file PR-fix for? Sounds like a good thing to generate a logged warning for (since user error isn't a true error, but a warning message to help user figure out they were the problem is super important)

@pnija
Copy link

pnija commented Nov 17, 2017

@lisad Applied your solution still getting "AuthStateMissing: Session value state missing". How did you solve it in production server?

@AnttiVirtanen
Copy link

Struggled with the exact problem for days, turned out that reason for missing state was caused by the caching. We had Django's LocMemCache on use (django.core.cache.backends.locmem.LocMemCache), changed it to MemcachedCache (django.core.cache.backends.memcached.MemcachedCache) and the problem disappeared.

@pnija
Copy link

pnija commented Nov 24, 2017

@AnttiVirtanen , I'm using django.core.cache.backends.memcached.MemcachedCache as our caching Server. still, the issue persists

@AnttiVirtanen
Copy link

@pnija Well that's fairly strange. Are you also using session based caching? And if so, which session engine? In case you are using django.contrib.sessions.backends.cache that might cause the problem too, quoted from django documentation "... session data may not be persistent".

@pnija
Copy link

pnija commented Nov 27, 2017

@AnttiVirtanen i'm using "django.contrib.sessions.backends.cached_db" as our session engine

@SteveChurch
Copy link

Is there any update on this issue?

@danielskun
Copy link

I have exactly the same issue. I am using Memcached in production and I have SESSION_COOKIE_SECURE = True.

@dsaves
Copy link

dsaves commented Jul 24, 2018

I also had this problem. Solved it by adding "SOCIAL_AUTH_REDIRECT_IS_HTTPS = True" in my settings.py file, since my configuration is using nginx to redirect to HTTPS. I found this answer only by reading the documentation here: https://python-social-auth-docs.readthedocs.io/en/latest/configuration/settings.html

@yuri1992
Copy link

We had that kind of problem as well.

After a long investigation, we found that those errors should occur in some of the cases.
When you are using Django, social_auth is saving the state secret inside the session object
and comparing it later on to the state been received from the provider.

We found out the some of our users, are sharing the already generated urls we providing for the social-auth (ex https://**provider**login/?next=/accounts/o/authorize/%3Fclient_id=CLIENT_ID&redirect_uri=RETURN_URL&state=GENERAED AND SAVE STATE IN SESSION&response_type=BLA)

When those users succesffully entered thier authetication details they been redirected back to our site and AuthStateMissing exception been raised.

My suggestion is to catch the AuthStateMissing exception in a middleware (django) and verified that session object is exists as needed for the state validation check, It it do existing go and dig futher, otherwise your are wasting your time.

@zain
Copy link

zain commented Nov 8, 2018

Another thing to try if you are seeing the AuthStateMissing error and you are using Django:
in settings.py, add SESSION_COOKIE_SAMESITE = None.

In my case, I only saw the error on Safari upon the redirect in the last leg of Oauth. The weirdest part was that I could refresh the page and the error would go away.

Upon further digging, I realized Safari wasn't sending any cookies on the redirect, but would send cookies when I hit refresh (so the cookies were set correctly, just not being sent). I found the SESSION_COOKIE_SAMESITE setting which, by default, will strip your cookies on that redirect, and thus Django cannot find your session.

@afwilkin
Copy link

afwilkin commented Sep 8, 2019

I was able to solve the issue by running an "Empty Cache and Hard Reload" in Google Chrome (https://www.thewindowsclub.com/empty-cache-hard-reload-chrome)

@jaywhy13
Copy link

I found the SESSION_COOKIE_SAMESITE setting which, by default, will strip your cookies on that redirect, and thus Django cannot find your session.

I'm having this same issue but I'm not sure how setting SESSION_COOKIE_SAMESITE to None helps. I'm a little concerned about the impact that will have site wide in terms of security. As I understand it, Lax will send cookies on a redirect, so it won't strip cookies on a redirect. Lax would however refuse to send cookies if in a cross-site context. So if a third party site is hosting an image or a script from our site, Lax would not send cookies to our server on those requests. Strict would strip cookies on a redirect from an external site.

@zain did changing the SESSION_COOKIE_SAMESITE abolish all your problems?

@zain
Copy link

zain commented Feb 28, 2020

@zain did changing the SESSION_COOKIE_SAMESITE abolish all your problems?

It did abolish all my problems. I recently discovered that the likely culprit was a bug in Safari. There’s some details here: https://code.djangoproject.com/ticket/30250

@jaywhy13
Copy link

Thanks @zain, I will give it a shot. I realize it's just the session cookie, I missed that earlier.

@tgdn
Copy link

tgdn commented Jun 5, 2020

Hello everyone, thanks for the awesome work you do, this library is great.
Now this issue still persists, and I don't think setting SESSION_COOKIE_SAMESITE to None is the right approach, it feels like I'm disabling a security feature, rather than solving the problem...

@johndavidmullen
Copy link

Hi I was getting AuthAlreadyAssociated error when 2 gmail accounts were saved in the browser. For example when you click your login with google button and you are redirected to google's site and asked which email you want to log in with. In this case, when I selected one of the accounts i would get the AuthAlreadyAssociated error. To fix this, I tried closing current session before logging in new user. Now I'm getting the AuthStateMissing error. I've tried everything suggested here but the problem persists in our https prod environment. Anyone able to solve this recently? 🙏

@tiago-peres
Copy link

I tried closing current session before logging in new user.

How are you doing that @johndavidmullen ? It should work fine if you're logging out the user first before trying to login with the other in the same browser.

@WeaverArtemSoft
Copy link

Hello. I am facing the same problem.
I tried all what you have been suggesting, but nothing worked for me.
I use Redis for caching, azuread-oauth2 after logging in to azure i send the state and code to http://localhost:8000/auth/o/azuread-oauth2/?state=""&code="",
Tried removing "/" and got cors error, even tho i allowed all

up on debugging i came across a function called self.get_session_state() inside social_core.backends.oauth.py
this function returns none. Though its (self) does point out to the right session.

Thank you :)

@WeaverArtemSoft
Copy link

Hello. I am facing the same problem. I tried all what you have been suggesting, but nothing worked for me. I use Redis for caching, azuread-oauth2 after logging in to azure i send the state and code to http://localhost:8000/auth/o/azuread-oauth2/?state=""&code="", Tried removing "/" and got cors error, even tho i allowed all

up on debugging i came across a function called self.get_session_state() inside social_core.backends.oauth.py this function returns none. Though its (self) does point out to the right session.

Thank you :)

When client asks for a redirect to azureAd stratagy: <social_django.strategy.DjangoStrategy object at 0x7fe4dbc29be0>
When client sends the state and code back to the server stratagy: <social_django.strategy.DjangoStrategy object at 0x7fe4d0829460>

@juvarabrera
Copy link

For some reason, I had SESSION_COOKIE_DOMAIN = 'localhost' in my settings.py. Removing this fixed my problem. hope it works to others too

@romulocollopy
Copy link

If you are running both in the same host, you can set different SESSION_COOKIE_NAME for each application

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests