Forums

Oauth issues (my guess)

Hello,

Did a bit googling and it seems there is an issue for oauth and pythonanywhere. It won't let my signin with a google account to my application at : http://mannanj.pythonanywhere.com/

But it does work on a local development version. After long time of googling I could not find any real solution, that did not say "Upgrade to a Paid version" of pythonanywhere. But I don't understand how that will fix it!

The error log is at: https://www.pythonanywhere.com/user/mannanj/files/var/log/mannanj.pythonanywhere.com.error.log and the specific error occurs at 2015-05-14 05:21:57,478 (around the last 50 lines of code)

Has anyone found a fix to this problem? Any help would be appreciated.

Hi mannanj,

Just so you know, other people (non-admins) would not be able to see your error log. I believe the reason upgrading to a paid account may fix this is because we limit outgoing internet access for free accounts. (ie. you won't be able to ask google to authenticate for you because you can't reach google)

The reason why we restrict outgoing internet access is that we have had a lot of problems with people using us to send spam/launch DoS attacks before. Having said that, we do make the exception for certain google endpoints. Maybe double check if the google auth endpt is in this whitelist?

Thanks for the quick response. I think at this point it is because I am a free user, because all I am using is flask_oauth and the google signin which is standard, but i don't know how to check if the google adpoint is on the whitelist? I am a bit of a newbie on this stuff.

I doubt i would choose a paid account anytime soon because this project is just in testing and I have been able to get this module to work on heroku, amazon cloud services so I don't see the point in paying right now when this project has not been approved for production by my company. Its unfortunate, for simple google signin I was turned off from this site. You guys have a great product, and staff who do their job well and quick.

btw- I just looked up the google oauth api, and wrote a webapp with flask that does google login successfully with a free account.

However, I did not use the flask_oauth library and just wrote my own couple lines of code. But that confirms that we are not restricting access to google's oauth api. I haven't looked at flask_oauth much at all- I do think it just flat out does not support python3- you wouldn't by any chance be using python 3 would you?

Please note that to use google oauth successfully, you will need to setup a bunch of stuff on google first, and you may have to pass in particular query parameters. In particular, you will need to set it up so that google knows that the login requests are coming from your pythonanywhere webapp. If you don't do this google will block you.

I did setup all the google parameters. But Guess what - I bought a paid account, and it started working instantly.

I decided to come back because Amazon cloud services are hard to figure out, and heroku does not offer local file storage (which I ma using instead of databases). Buying a paid account fixed it.

At this point I wont need to look into not using flask_oauth, but for curiosity reasons how did you write the google signin without flask oauth if you wouldn't mind sharing the code?

Woh weird. Sorry about that. Maybe it's something else that flask-oauth is doing.

I just made it so that when you go to the root/index page, you are redirected to do google signin. Then if the user signs in correctly, google just hits your callback page with an auth code, which you then convert into an access token by sending a POST request with the auth code to google. Finally you can do something like get the email of the user using the auth code.

If you look at the google endpts that I've hit, they should all be accessable via a free account. (eg: a simple test would be if you just curl it, and google would respond that you haven't given the correct token) I have also put it on a free account to test out as well.

Here is the github repo for the (quite sloppily written) python3.4 flask app. It is <50 lines long, so I guess simple-ish? But figuring out the correct urls and parameters etc was definitely quite annoying, and hopefully google won't randomly change the api endpts... For anyone trying to set this up on pythonanywhere, you also need to add environment variables in your wsgi file, and make sure the redirect URIs are pointing to your own webapp both in my code and in your google developers console credentials.

Perhaps, i don't see the point in looking into it further if it started working now. It was oauth 2 protocol, i dont know if that has anything to do with it.

Thank you for sharing the github repo! Figuring out the url stuff is definitely going to be annoying, luckily i've done a bit of that already for oauth2 so it shouldnt be too hard.

hmm. to clarify the stuff I did was oauth 2 as well. We would have to dig into the flask_oauth code to figure out what the difference is. There may be some other specific api endpts that we did not whitelist. but yes- let's just leave working be for now! :p

Hello guys,

I've encountered a very similar problem.

My app is http://seabrus.pythonanywhere.com. My account on PA is free. I use Python 2.7, Django 1.8.5, and Django REST Framework 3.3.1.

The login subsystem is built on the base of Django AllAuth 0.24.1 package. I use it in two ways - via its basic functionality (the "LogIn" menu item) and via the "django-rest-auth" package ("Google LogIn" item in the menu). The second one is developed for using with the REST API from the Angular client side. I request a access_token from Google, using the received token I prepare and send a POST request to a django-rest-auth view, and django-rest-auth finishes the work with Google's server itself (btw, it uses AllAuth's module for this task).

Locally this works fine. But on PA I have the answer "500 Server error" in both cases "LogIn > Google" and "Google LogIn". The latter means that the initial request from the client to Google's server is OK, I get a correct answer, but when django-rest-auth starts server-to-server requests, it fails.

I've checked carefully the Google account settings and my code. The difference with conrad's example is that I use Google's "access_token", not "code" in my requests to Google.

From the discussion above it looks like I need to use a paid account on PA, right? Or maybe there are some other recommendations?

Thanks in advance for replies.

A paid account should definitely fix the problem.

The alternative is to try to debug at what point the server-to-server request is failing. There are two possiblities:

  • It's trying to access a server that's not on our whitelist. We'd be happy to whitelist a Google oauth server, and we think we have, but there's a possibility we've missed one. If you can get enough debug information to identify the hostname of the server the code is trying to connect to, we can whitelist it. An indicator that this would be the problem would be if the 500 internal server error was being caused by an underling 403 "forbidden" exception raised by the code doing the server-to-server call.
  • It's ignoring the HTTP proxy settings in the environment. Most modern HTTP request libraries (like requests) look at the http_proxy and https_proxy environment variables, and if there's something in there, they use that proxy to access other servers. This is necessary for code running under a free account, as the proxy is what handles the whitelist. (Paid accounts completely bypass the proxy so this isn't an issue. But some older HTTP request libraries require specific configuration to use a proxy, so if the AllAuth module is using one of those and isn't passing proxy information through, that could be the problem. An indicator that this is the problem would be if the 500 is being raised because of an underlying error like "111 Network unreachable".

So, if you look at your web app's error logs, perhaps you'll be able to identify which (if either) of these problems it is?

Hi,

Thanks a lot for your prompt reply!

Here is the requirement.txt for this app:

  • Django==1.8.5
  • djangorestframework==3.3.1
  • Markdown==2.6.5
  • django-filter==0.11.0
  • django-allauth==0.24.1
  • python-openid==2.2.5
  • requests==2.8.1
  • requests-oauthlib==0.5.0
  • oauthlib==1.0.3
  • django-rest-auth==0.6.0
  • Pillow==2.6.1 # the local OS is ubuntu 10.04, so this Pillow version is OK
  • six==1.10.0
  • wheel==0.24.0

As I can understand, AllAuth's core class GoogleOAuth2Adapter uses the following urls:

  • access_token_url = 'https://accounts.google.com/o/oauth2/token'
  • authorize_url = 'https://accounts.google.com/o/oauth2/auth'
  • profile_url = 'https://www.googleapis.com/oauth2/v1/userinfo'

My error.log is empty.

access.log contains such records as this one:

[23/Dec/2015:18:56:26 +0000] "POST /rest-auth/google/ HTTP/1.1" 500 38 "http://seabrus.pythonanywhere.com/rest-auth/google/" "Mozilla/5.0 (X11; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0"

No 403 or 111 status at all.

If some other info can be useful, I'm glad to provide it.

Thanks for that! Interesting.

So, all of those URLs should be OK -- specifically, we whitelist *.google.com and *.googleapis.com. So I don't think it's a whitelisting problem. That leaves the proxy issue. But you do have requests in your requirements file, and a quick look at the AllAuth code for their Google auth handler suggests they're using it. So it should be picking up our proxy settings.

Hmm. Do you have DEBUG mode set to True in the settings.py? If not, try turning it on and see if you get a more helpful error page.

You was absolutely right - sometimes DEBUG=True is the greatest way to find out the truth :)

Sorry, it was my fault -- I forgot to set up some specific AllAuth settings. These settings are not saved in the settings.py or other persistent places, and they should be redefine when deploying the app.

Now Google login works fine.

Thank you very much for your time and great support!

Cool. Glad you got that worked out.