omniauth-oauth2: google_oauth2 Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
Even when creating the state myself it got the same error.
session['omniauth.state'] = SecureRandom.hex(24)
redirect_to "/auth/google_oauth2?state=#{session['omniauth.state']}"
Even though the returned state is the same, meaning it should match !
Isn’t there a double redirect or something ? Because if so the :
request.params['state'] != session.delete('omniauth.state')
in https://github.com/intridea/omniauth-oauth2/blob/master/lib/omniauth/strategies/oauth2.rb#L72 would explain the problem. => First passes, second fail.
About this issue
- Original URL
- State: closed
- Created 10 years ago
- Comments: 67 (4 by maintainers)
Commits related to this issue
- Update README.md Many people use the snippet from Usage section and then configure the same thing with Devise. This leads to strange errors - see intridea/omniauth-oauth2#58. — committed to Nowaker/omniauth-google-oauth2 by Nowaker 9 years ago
- Fix broken team_id to email_domain — committed to willhall88/jekyll-google-auth by deleted user 9 years ago
- Fix issue when using Safari to authenticate https://github.com/omniauth/omniauth-oauth2/issues/58#issuecomment-347280092 — committed to VitaliyAdamkov/solidus_social by VitaliyAdamkov 6 years ago
- Fix issue when using Safari to authenticate https://github.com/omniauth/omniauth-oauth2/issues/58#issuecomment-347280092 — committed to VitaliyAdamkov/solidus_social by VitaliyAdamkov 6 years ago
- Fix issue when using Safari to authenticate https://github.com/omniauth/omniauth-oauth2/issues/58#issuecomment-347280092 — committed to VitaliyAdamkov/solidus_social by VitaliyAdamkov 6 years ago
For whatever its worth , I had all these issues because I had my clientId and secret in both my omniauth.rb file as well as my devise.rb config file. I mistakenly did this following the omniauth-google-oauth2 gem instructions. Now I only have the line below in devise.rb. config.omniauth :google_oauth2, client, secret
No omniauth.rb file needed.
This problem occurs with rails when the domain defined in
/config/initializer/session_store.rbis different from the origin/redirect_uri defined in the google api console.Removing the domain params or using the same domain on both sides (plus activating contacts and google+ APIs in console…) fixed the problem for me.
I think we can close this issue! 😸
I have been wrestling with this all day, but none of the above helped.
I finally realized that this is happening to me on staging because staging is at staging.example.com and production is at example.com, so both production and staging cookies are being sent to staging. Staging will work most of the time, but then if I go use production and come back to staging, I get one more valid request and then need to re-authenticate. After returning from authenticating with Google, it threw csrf_detected until I cleared cookies. It would then work fine until some seemingly random time in the future that I now attribute to my having interacted with production.
I’m leaving this note here because Google kept leading me back to this issue, so perhaps it will help someone else.
I was getting this error in a rails app and the way to reproduce it was to initiate two oauth2 logins at the same time. This caused one of the logins to fail with CSRF error, because its random string in the state params get invalidated by the second login request.
Just something to keep in mind if you get this error from time to time and you can’t figure out why.
Help me please to slove the issue of csrf-error Please do tell me urgently… not able to authenticate facebook…
/usr/local/var/rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/omniauth-google-oauth2-0.2.3 scopes changed. same error.
I had this exact same problem and adding
domain: 'localhost'insession_store.rbfixed it for me. Thanks everyone!For me the reason this happened was non of the above so I thought I’d share what solved it for me. Maybe it can save someone else a few hours of headache in the future.
Following this change introduced in Google Chrome behavior, we started adding
SameSite=Noneto allSet-Cookieheaders. But, Chrome also ignoresSet-Cookieheaders that haveSameSite=Nonebut are missing theSecureattribute. And, since I was running this on localhost, without HTTPS, theSecureattribute was not added.So as a result, my session cookie wouldn’t get created on the browser because Chrome would ignore its
Set-Cookieheader, resulting in a new session created on each request, and a failed state comparison.So if your app is setting
SameSite=Noneto the session’sSet-Cookieheader like this or for all cookies with this gem or this gem, and you’re getting this error when running locally, you should do one of the following:chrome://flags/, disable “Cookies without SameSite must be secure”Or
Hope this helps.
Update (Nov 25th 2021):
I also had a problem with this and by chance I found out that visitors using naked domain (non-www) got this error.
After some digging I found the source to my problem:
callback_urlwas set to the www subdomainThere are a few different solutions to this:
I went with redirecting the traffic to www, since it was better suited for my given situation. There are multiple ways to redirect the traffic, e.g using Rails routes:
lol yeah. fixed 😉
Well everything works fine when I use the ugly
option. Thus I’m sure my credentials are ok.
For the record I also use other options, but quite sure it has nothing to do with the present problem :
If you got this error with Safari, then try Firefox and Chrome. If only Safari has this issue, then my answer may help, because I spend hours to figure it out.
The problem is, like this URL http://example.org/auth/my-strategy, Safari will send two requests.
The first request to onmiauth, will generate a
state, then redirect tomy-strategylogin, after login successfully, redirect back to my-strategy callback http://example.org/auth/my-stragegy/callbck with sstateparameter, at this time Omniauth will compare thestatevalue between session and callback parameter.The second request is going after the first request, it makes Omniauth generate another
state.See, the callback
stateparam of the first request has not to be the same ofstatein session, that’s why we gotCSRF detectederror.To fix it, I add a timestamp to login URL, http://example.org/auth/my-strategy?t=12345678, Safari won’t request this URL twice when I click it.
currently we’re using the same
session["omniauth.state"]to store incomingparams[:state]if we give each state its own namespace, then multiple requests won’t trample over each other?
with default
:cookie_store, there is still risk of overwriting each other. i ended up monkey patching withRails.cacheinsteadHey all,
I’d just like to point out that this is still broken under some conditions: namely, if you start making multiple requests from you’re app, and during that time initiate an auth request, there’s a race condition that causes the session cookie that holds the state to be clobbered.
Specifically, -Request 1 for some resource hits you’re server, and begins doing something that requires a lot of computation/lookups. -Auth request is created -Auth request (with state information) is returned, cookie is updated -Request 1 returns, cookie is overwritten by Request 1’s cookie (which didn’t have the session state in it) -User finishes authorizing with 3rd party, callback is initiated, and request.params[‘state’] is empty
Just wanted to add to the thread, as I wound up here after some quick googling as well. I solved this by doing something specific within my app space (message if you’d like to hear what, but its more of a case-by-case thing) - if theres something I’m missing though that would have solved this would love to hear it!
here is my way
provider :provider, APP_KEY, APP_SECRET, provider_ignores_state: Rails.env.development?@gdurelle Thanks for clarifying.
I ran into the same problem with omniauth-github, and
provider_ignores_state: true“fixed” it, but as @NickTomlin wrote above, usingprovider_ignores_state: truefeels wrong. But I haven’t had time to look into the problem more. I don’t think there’s a need to reopen.Ours ended up being a race condition where a second request was clearing all the relevant omniauth fields from the session before we’d gotten through the callback phase
Is this issue related to google issue https://code.google.com/p/gdata-issues/issues/detail?id=6628 wherein occasionally two requests are sent back from google account login?
Strangely, I’m seeing this on iOS safari, but not iOS chrome or mac/pc im using facebook omniauth
FWIW, if anyone else comes here with the same issue - I had the same error happen with Hybrid Auth; adding provider_ignores_state in omniauth setup fixed it.
Then another separate bug appeared with invalid_client; which was way more easier to handle - PEBKAC 😃
i’ve been banging my head against this issue for far too long to not leave a comment here letting others know what worked for me.
for context: i’m using oauth within a mounted rails engine. the issue was that the main rails app the engine was mounted in was using https via
force_sslbut the engine was not. this caused the server to randomly bounce between http and https, which both caused the csrf error and trashed the session.if you’re reading this, i hope it helps you to not lose two and a half days to debugging like i did. godspeed!
Guys, can you point us to some steps to solve this issue. I can’t figure out what to monkey patch according to @choonkeat solution. I hope if you point out some directions.
This is the solution that worked for me. http://stackoverflow.com/a/25112048
Basically remove omniauth.rb and set you configuration in devise.rb. look for around line 238
@jwg2s Please have a look at my PR - that was the reason why I faced this. Maybe your case is very same. https://github.com/zquestz/omniauth-google-oauth2/pull/190/files
Is there a safe version that doesn’t suffer from this issue? I am experiencing the same thing and have tried provider_ignores_state, domain in session store, and skipping devise authentication for the omniauth controller. I’m at a loss.
@austinwang +1 I removed the wrong initializer and it works now !
After some tests, its appear that session[‘omniauth.state’] is nil during the callback phase! Why session doesn’t keep it?