-
Notifications
You must be signed in to change notification settings - Fork 388
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
Authomatic Usecases #1
Comments
The first usecase of Authomatic is apparently the live demo running at: |
I wanted to use this, after seeing a demo. Unfortunately, the demo application you have hosted on GAE is not working. |
@SVarier, what exactly is not working on the on-line demo? There was a problem with Google when user profile response contained unicode characters which could not be decoded to ASCII, but that was a bug of the demo app, not Authomatic. The bug is now fixed. |
Hi Peter, is authomatic for google OAuth2 authentication working - particularly using the werkzeug adapter? I keep getting None result. |
Which of the Google sign in flows is being implemented by Authomatic?: https://developers.google.com/+/web/signin/ |
@pbvillaflores, Yes, it is working. If the @app.route('/login/<provider_name>/', methods=['GET', 'POST'])
def login(provider_name):
response = make_response()
result = authomatic.login(WerkzeugAdapter(request, response), provider_name)
if result:
# Login procedure is over
if result.user:
# Success
response.data += 'Hi {0}'.format(result.user.name)
elif result.error:
# Error
response.data += 'Something went wrong: {0}'.format(result.error.message)
# If there is no result, the login procedure is not over yet
return response |
@webmaven, Automatic implements the server-side flow. |
The example code at
From: Peter Hudec [mailto:[email protected]] @pbvillaflores https://github.com/pbvillaflores , Yes, it is working. If @app.route('/login/<provider_name>/', methods=['GET', 'POST'])
Reply to this email directly or view |
@pbvillaflores, Yes, you're right. the result of the login procedure is a response with an access token. Most of the providers don't provide the user profile information in this response, although some do. Therefore to get the user profile info you need to make a protected resource request with the access token to get the user name. This is intentional because not everybody needs the user profile info but rather just the access token. The best way is to call the method only if there is not the user info you need: ...
if result.user:
# Success
if not result.user.name:
result.user.update() # Makes a provider API call internally
# The above statement internally calls
response = authomatic.access(result.user.credentials, 'https://graph.facebook.com/me')
user_info = response.data # Parsed JSON
response.data += 'Hi {0}'.format(result.user.name) |
So, I wonder what is the correct way to structure that portion of the login if result.user: OR: if result.user: From: Peter Hudec [mailto:[email protected]] @pbvillaflores https://github.com/pbvillaflores , Yes, you're right. the ...
Reply to this email directly or view |
If there is user, it is always success. But most of the time you only have an access token of the user. Some providers do not provide user profile info at all. A better solution would be to check the response status of the if result.user:
if not result.user.name:
response = result.user.update()
while response.status != 200:
response = result.user.update() |
should we add after each call to user.update::
|
The update_success = True if result.user.update().response.status == 200 else False |
I get 403 forbidden on OAuth2 with google |
But I have the same thing working with FB |
In which phase are you getting the error? Could you provide the logs? |
Google should provide information why it is a forbidden 403 request. Try |
I am trying to still figure out how to get the logging to work correctly. Maybe you can help also with this. I've set it at the instance authomatic creation line added logging_level, but no joy. Anyway, the run has already reached these bits of OAuth2 code:
# exchange authorization code for access token by the provider
self._log(logging.INFO, 'Fetching access token from {0}.'.format(self.access_token_url))
The google response result is: |
This looks like you have an access token but not for reading the user profile. Did you set the user info scope in the config? CONFIG = {
'google': {
'class_': oauth2.Google,
'consumer_key': '##########',
'consumer_secret': '##########',
'scope': ['profile'],
}
} |
that didn't change the outcome. isn't profile and email already included by default in scope? |
No, you need to set it explicitly. There is however the |
If you comment out the |
No. From: Peter Hudec [mailto:[email protected]] If you comment out the result.user.update() does the user have the token Reply to this email directly or view |
could you please provide the code of the whole view? |
its messy, but what i have currently is:
|
I managed to get the logs...
INFO:authomatic.core:authomatic: Google: Starting OAuth 2.0 authorization procedure.
INFO:authomatic.core:authomatic: Google: Redirecting user to https://accounts.google.com/o/oauth2/auth?scope=profile+email+profile&state=6a30d07f08b2ff116664183a6c&redirect_uri=http%3A%2F%2F127.0.0.1%3A5000%2Flogin%2Fgoogle&response_type=code&client_id=600898592185-ui9jov18q0083hjce3rtr45ges2f735t.apps.googleusercontent.com.
INFO:werkzeug:127.0.0.1 - - [14/Jul/2014 22:41:10] "GET /login/google HTTP/1.1" 302 -
INFO:authomatic.core:authomatic: Google: Continuing OAuth 2.0 authorization procedure after redirect.
INFO:authomatic.core:authomatic: Google: Validating request by comparing request state with stored state.
INFO:authomatic.core:authomatic: Google: Request is valid.
INFO:authomatic.core:authomatic: Google: Fetching access token from https://accounts.google.com/o/oauth2/token.
DEBUG:authomatic.core:authomatic: Google: ├─ host: accounts.google.com
DEBUG:authomatic.core:authomatic: Google: ├─ path: /o/oauth2/token
DEBUG:authomatic.core:authomatic: Google: ├─ method: POST
DEBUG:authomatic.core:authomatic: Google: ├─ body: client_secret=Mx234234&code=4%2Fb62342340cxpjgI&grant_type=authorization_code&client_id=600898592185-ui9jov18q0083hjce3rtr45ges2f735t.apps.googleusercontent.com&redirect_uri=http%3A%2F%2F127.0.0.1%3A5000%2Flogin%2Fgoogle
DEBUG:authomatic.core:authomatic: Google: ├─ params: {'client_secret': '234234234sdfwrfNwVKIMjt', 'code': u'4/b6l227IHJAiJOzZHG6GmHb_cnV14.IqjksOW8cPQfBrG_bnfDxpIu0cxpjgI', 'grant_type': 'authorization_code', 'client_id': '60089859218123q0083hjce3rtr45ges2f735t.apps.googleusercontent.com', 'redirect_uri': u'http://127.0.0.1:5000/login/google'}
DEBUG:authomatic.core:authomatic: Google: └─ headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic NjAwODk4NTkyMTg1LXVpOWQuY29tOk1ZX0NIYTZNTFd4Y1BYUUlOd1ZLSU1qdA=='}
DEBUG:authomatic.core:authomatic: Google: Got response:
DEBUG:authomatic.core:authomatic: Google: ├─ url: https://accounts.google.com/o/oauth2/token
DEBUG:authomatic.core:authomatic: Google: ├─ status: 200
DEBUG:authomatic.core:authomatic: Google: └─ headers: [('alternate-protocol', '443:quic'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('content-disposition', 'attachment; filename="json.txt"; filename*=UTF-8\'\'json.txt'), ('transfer-encoding', 'chunked'), ('expires', 'Fri, 01 Jan 1990 00:00:00 GMT'), ('server', 'GSE'), ('pragma', 'no-cache'), ('cache-control', 'no-cache, no-store, max-age=0, must-revalidate'), ('date', 'Mon, 14 Jul 2014 12:41:42 GMT'), ('x-frame-options', 'SAMEORIGIN'), ('content-type', 'application/json; charset=utf-8')]
INFO:authomatic.core:authomatic: Google: Got access token.
INFO:authomatic.core:authomatic: Google: Procedure finished.
INFO:authomatic.core:authomatic: Google: Accessing protected resource https://www.googleapis.com/plus/v1/people/me.
DEBUG:authomatic.core:authomatic: Google: ├─ host: www.googleapis.com
DEBUG:authomatic.core:authomatic: Google: ├─ path: /plus/v1/people/me
DEBUG:authomatic.core:authomatic: Google: ├─ method: GET
DEBUG:authomatic.core:authomatic: Google: ├─ body:
DEBUG:authomatic.core:authomatic: Google: ├─ params: {}
DEBUG:authomatic.core:authomatic: Google: └─ headers: {'Authorization': 'Bearer ya29.QgD29DpKW7rdoEcAAADZeyO23424234234234243234LwZ5vHmA'}
DEBUG:authomatic.core:authomatic: Google: Got response:
DEBUG:authomatic.core:authomatic: Google: ├─ url: https://www.googleapis.com/plus/v1/people/me
DEBUG:authomatic.core:authomatic: Google: ├─ status: 403
DEBUG:authomatic.core:authomatic: Google: └─ headers: [('alternate-protocol', '443:quic'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('transfer-encoding', 'chunked'), ('expires', 'Mon, 14 Jul 2014 12:41:43 GMT'), ('server', 'GSE'), ('cache-control', 'private, max-age=0'), ('date', 'Mon, 14 Jul 2014 12:41:43 GMT'), ('x-frame-options', 'SAMEORIGIN'), ('content-type', 'application/json; charset=UTF-8')]
INFO:authomatic.core:authomatic: Google: Got response. HTTP status = 403.
|
According to the logs everything went fine. Try this simple handler: @app.route('/login/<provider_name>/', methods=['GET', 'POST'])
def login2(provider_name):
response = make_response()
result = authomatic.login(WerkzeugAdapter(request, response), provider_name)
if result:
if result.user:
result.user.update()
return 'Hi: {0}'.format(result.user.name)
elif result.error:
return 'Error: {0}'.format(result.error.message)
return response |
I have reorganized your code a little bit: @app.route('/login/', methods = ['GET', 'POST'])
def login2(provider_name):
print ">= request.base_url: ", request.base_url
if g.user is not None and g.user.is_authenticated():
return redirect(url_for('index'))
response = make_response()
result = authomatic.login(WerkzeugAdapter(request, response), provider_name)
if result:
if result.error:
return 'Something went wrong: {0}'.format(result.error.message)
if result.user:
if not result.user.name:
update_response = result.user.update()
while update_response.status/100 not in [4,5]:
update_response = result.user.update()
if update_response.status/100 in [4,5]:
return 'Response status: {}'.format(response.status)
if result.user.name is None:
result.user.name = "Got None"
result.user.email = "[email protected]"
else:
flash("Logged in successfully id=" + result.user.id)
user = User.query.filter_by(email = result.user.email).first()
if user is None:
nickname = result.user.name
if nickname is None or nickname == "":
nickname = result.user.email.split('@')[0]
nickname = User.make_unique_nickname(nickname)
user = User(nickname=nickname, email=result.user.email, role=ROLE_USER)
db.session.add(user)
db.session.commit()
g.user = user
login_user(g.user, remember=True)
return redirect(request.args.get('next') or url_for('index'))
return response |
|
Using the simple view code, I get: |
I've resolved that last issue by clearing cookies. But the result using the simple handler code is still the 403 forbidden error and I get user is None. |
yahoo! Solved it. So, the error message is available in: And the solution was to enable google+ API in the APIs menu of the google dev console. Thanks Peter! |
The other problem now is that when I use FB OAuth2 with the app running on heroku, I get: in login2() handler: Something went wrong: Failed to obtain OAuth 2.0 access token from https://graph.facebook.com/oauth/access_token! HTTP status: 400, message: {"error":{"message":"This IP can't make requests for that application.","type":"OAuthException","code":5}}. And it seems no matter how I update the IP address whitelist on the FB dev console, I can't get the app to successfully authenticate through. It did work before already, but now it isn't. |
Great! I will add a note about enabling the Google+ API to the docs. The other issue seems to be a Facebook bug: http://stackoverflow.com/questions/12072720/oauth-error-this-ip-cant-make-requests-for-that-application. |
Thanks again. BTW, I assume the FB authentication cannot be made open to the From: Peter Hudec [mailto:[email protected]] Great! I will add a note about enabling the Google+ API to the docs. The Reply to this email directly or view |
You are very welcome. |
Hi, Thanks for writing this wonderful library. While running your credentials example, I'm not able to post tweet. I have given Read and Write permission to my app. When I try to post, I get Internal Server Error and in GAE logs I get AttributeError: type object 'Twitter' has no attribute '_logger' |
fix an error i was getting with yahoo openid
I have this error message:
help!!! :( |
Please use stackoverflow to ask questions. |
I would love to hear from you in comments below whether you use Authomatic, how you use it, why you use it or why you don't.
The text was updated successfully, but these errors were encountered: