Master: | |
---|---|
Develop: |
Oauth provider login and APIs for use with Flask-Security
OAuth Provider Integration for Flask-Security
License: MIT License
Master: | |
---|---|
Develop: |
Oauth provider login and APIs for use with Flask-Security
There are great examples of the config for the different tokens (Twitter and Facebook) in the README.md.
It would also be nice to have an example of how to input the configuration values.
Right now I am not sure how to properly input the configuration since this format crashes
app.config['SOCIAL_CONNECT_DENY_REDIRECT'] = "/done"
Related to my Stackoverflow question.
Thanks for a great Flask extension.
As mentioned in issue #28, I am opening this issue to discuss the goals of the Develop
branch and establish a common plan of attack for adding features and new social connections.
Develop
branch currently are, so @mattupstate if you could give a brief idea on that, it would be very helpful.Develop
, I don't think it makes sense to add features or social connections to it. If we get an idea about (1) we can work on that.@mattupstate, @alexef, @hari-n you PRs all relate, so curious on your thoughts!
The examples and view code assume the use of the DELETE method to remove connections, but most (if not all) browsers don't allow DELETE as a method for regular forms.
Is there any way to register user using your library?
I want to let user register in one click and let him log in in the same fashion.
Right now i have social registration using oauth-request-lib, but i would like
to integrate it with your framework.
I'm using the Facebook JavaScript SDK to implement Login with Facebook in a Flask project. I've written some code to integrate with Flask-Social and am wondering if this is something that could be cleaned up and contributed back to the project.
The idea behind the facebook_login
view is that, once the FB.login()
JavaScript function has authenticated the user, the access_token (and user_id) are POSTed to the application server to log the user in. In my case, I also want to create accounts for users who don't already have them, but that behavior would of course be optional.
The advantage of using the Facebook JavaScript SDK to handle authentication, instead of using the OAuth-based redirect flow of stock Flask-Social, is that the Facebook authentication page opens in a new window instead of relying on a redirect to return to the application. It's a more seamless user experience.
I don't think this is necessarily Facebook-specific, other social sites may have similar JavaScript SDKs that handle all the authentication details and just expose an access_token and user_id when they're ready.
Thoughts? Is this something worth integrating back into Flask-Social somehow?
I'm trying to implement a Login-with-LinkedIn functionality on my Flask website. I'm currently starting to build something flask-oauthlib. Since I'm a noob with OAuth I wonder whether flask-social also supports LinkedIn and whether it is easier to use flask-social or flask-oauthlib?
All tips are welcome!
Google oauth1.0 is deprecated
It would be awesome if it were possible to log in w/ a social account only. Meaning there would be no need to enter email or passwords.
Apparently others are looking for this as well (I did not create this stack post): http://stackoverflow.com/questions/17998627/using-flask-social-with-oauth-providers-only-no-local-registration-login-form
Would it be possible to create a new version for pypi? I would love the updates from the google provider (scopes and get_api).
Thanks!
Facebook Access Tokens can expire, so we should allow for the connection and login routes to update the connection data even when it already exists. Going to mull this over and work on an implementation. Any input would be greatly appreciated.
Also, it would be handy in this situation to be able to logout a user without the app context, in the case that you experience this error in a background task. Is there an easy way to do this that anyone knows off the top of their head?
Is there a way to ensure that users who register or connect with an Oauth account are not using this Oauth'ed account more than once across the system? In other words, can we prevent users from connecting or using their Twitter account on multiple accounts on our site? I tried googling and searching the docs, to no avail. I assume this would be a good feature for most sites.
This project's last commit occured in 2014, and there are many issues and merge requests that are many years old. Is this project still maintained? If it's not, are you aware of any viable alternative?
I am using mongo and I don't have the exact same fields as the dict in the facebook plugin:
full_name = profile.get('name', None),
I actually have 'name' and not 'full_name'.
Can I provide my own facebook.py somehow? I could not work out how.
Maybe it's easy. This code from core.py is close but it adds the module path.
default_module_name = 'flask_social.providers.%s' % suffix
module_name = config.get('module', default_module_name)
module = import_module(module_name)
(I could also monkeypatch get_connection_values and put my own facebook to mongo decoder. Not approved. )
urlparse is renamed to urllib.parse in python 3.x
I assume you only support 2.x versions, is there any plans for 3.x compatibility?
I start some work to add python 3.x support. If someone else do same thing please let me know, we can cooperate maybe ๐ .
https://travis-ci.org/mattupstate/flask-social/jobs/246424668
--use-mirrors seem to be breaking things.
Flask-WTF has a great function, CsrfProtect
that will raise an exception whenever a non-GET request is made if the route doesn't check for a form validation. In fact, without this, functions like remove_connections
are currently vulnerable to a csrf attack.
Implementation is fairly simple. In the view functions we just:
from flask_wtf import Form
...
def view_func():
form = Form()
if form.validate_on_submit():
#do stuff
and in the template, when any such form if used, we just add:
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
@mattupstate wanted to get your opinion on implementation before I work too far on this. @talos will likely also be working with me on it as well, so if any input from either of you would be great.
I was thinking for the first part, we'd want to wrap it in a config check, app.config['CSRF_ENABLED']
that is set by calling the CsrfProtect
function. It might be useful to also set an override, app.config['SOCIAL_CSRF_ENABLED']
, but this might be overkill and over complicated.
Also, the template stuff is obviously a change to Flask-Social-Example. I think it makes sense to turn it on for the example, both since it's a good practice to use something like CsrfProtect
, and so that we can have the example reflecting that use case.
in core.py
47 def get_connection(self):
48 return _social.datastore.find_connection(provider_id=self.id,
49 user_id=current_user.id) <<<------ HERE
50
51 def get_api(self):
52 module = import_module(self.module)
53 connection = self.get_connection() <<--- Get_connection assumes current_user.
54 if connection is None:
55 return None
56 return module.get_api(connection=connection,
57 consumer_key=self.consumer_key,
58 consumer_secret=self.consumer_secret)
User id is hard coded to the current_user. Requesting parameters to pass user. This may be required when social activities are done in a different context than a normal request.
Have a commit coming shortly.
I'm attempting a standard implementation per the current tutorial of flask-social 1.6.2 with Flask 0.10.1 with SQLAlchemyDatastore
running on localhost. After a user has authorized the app on Facebook and attempts to log in, this error occurs.
The only spot I've diverged from the quickstart is adding full_name
to the Connection
class because it was getting returned by the Facebook provider and throwing an error not being in the model.
class Connection(db.Model):
...
full_name = db.Column(db.String(255))
I thought perhaps it was actually looking for user id, but digging a little deeper to login_user(...)
in flask_login.py
states Logs a user in. You should pass the actual user object to this.
I'm not sure if I'm doing something wrong in my implementation, or if this is actually a bug.
Full traceback after clicking the Login with Facebook
button:
Traceback (most recent call last):
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask_social/views.py", line 215, in login_callback
return login_handler(response, provider, query)
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask_security/decorators.py", line 205, in wrapper
return f(*args, **kwargs)
File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask_social/views.py", line 171, in login_handler
user = connection.user
AttributeError: 'Connection' object has no attribute 'user'
I'm trying to get a very basic version of the develop branch of flask-social working, code here and I'm getting an OAuth Error when I try to connect with twitter. (I have the app tokens stored locally).
The traceback I get is:
Traceback (most recent call last):
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/erik/Documents/workspace/flask-social-example/app/middleware.py", line 16, in __call__
return self.app(environ, start_response)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask_security/decorators.py", line 209, in wrapper
return f(*args, **kwargs)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask_social/views.py", line 49, in login
return provider.authorize(callback_url)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask_oauth.py", line 331, in authorize
token = self.generate_request_token(callback)[0]
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask_oauth.py", line 299, in generate_request_token
type='token_generation_failed')
OAuthException: Failed to generate request token
Any ideas?
The documentation on https://pythonhosted.org/Flask-Social/ is a little out of date. For example, there now needs to be a full_name field in the connection table, which is not presented there.
Also, it would be nice to indicate that the Twitter app thats created needs to allow for sign-ins (ok, thats kinda obvious I suppose) and that a callback URL needs to be specified. Maybe give some snap shots of the application settings for each provider?
It will be nice to create an example using mongoengine
Stack trace:
Exception on /login/facebook [GET]
Traceback (most recent call last):
File "/home/../pybox/local/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
...
File "/home/../pybox/local/lib/python2.7/site-packages/flask_social/views.py", line 205, in login_callback
response, query = provider.authorized_handler(login)()
TypeError: 'BaseResponse' object is not iterable
Is there an example of using Flask-Social that does not use Heroku/Vagrant? I'm looking for a small example that demonstrates the following:
I was trying this module and works great. But If a have an application already authorized in Twitter and I do logut/login, Twitter requests authorization again. I tried this with the example application and the problem is the same. It doesn't happen with Facebook. I'm not sure if it's a Twitter limitation or a limitation in Flask-Social.
I get the following:
AttributeError: 'bool' object has no attribute 'get'
Hello!
I am setting up a simple app using Flask-Social for Facebook OAuth login. When I click the facebook login button, however, I go to Facebook (have to enter my email/pass if I'm not already logged in) and then I'm stuck on a blank white page (https://www.facebook.com/dialog/oauth with a redirect_uri).
The same thing happens if I try to log in with facebook to the flask-social-example site (http://flask-social-example.herokuapp.com/). I tried with another OAuth2 implementation (using a different library) and the auth flow worked fine.
Thanks!
Is this correct?
dependency_links=[
'http://github.com/mattupstate/flask-security/tarball/develop#egg=Flask-Security-1.3.0-dev'
],
The use of "encrypt_password()" is not documented anywhere so figuring out how to properly encrypt passwords took hours of my time. Thanks.
Tested logging a user into facebook, twitter & google.
Redirects after registration are not working correctly:
The login is successful and redirects back to the application at the standard /login/ endpoint. From here it redirects to /login and then to /. Both SECURITY_POST_LOGIN
and SOCIAL_CONNECT_ALLOW_VIEW
are set to /profile
so it should be redirecting there.
I'm using this code for the registration view:
@login_failed.connect_via(app)
def on_login_failed(sender, provider, oauth_response):
connection_values = get_connection_values_from_oauth_response(provider, oauth_response)
ds = security
email = connection_values['email']
user = ds.datastore.create_user(
email=email,
username=email,
password=create_random_password()
)
ds.datastore.commit()
connection_values['user_id'] = user.id
connect_handler(connection_values, provider)
login_user(user)
db.session.commit()
return render_template('profile.html', user=user)
I can see that the user is added to the database and the connection is made. The redirect fails to work.
In reference to this comment, I suggest including a full_name
attribute to the dictionary returned from get_connection_values()
in each of the providers/provider.py.
For Facebook, it would look like:
display_name = profile.get('username', None)
full_name = profile['name']
This shouldn't break the API, unless someone is using display_name
assuming it never falls back to profile['name']
. This is more explicit, and should encourage people to use provider_user_id
rather than display_name
for any url building or other API access.
For Twitter, it would look like:
display_name = '@%s' % user.screen_name,
full_name = user.name
If there is support for this change, I will submit a pull request.
If a user registers or logs in cold from Twitter, but hits "Cancel" on Twitter, the module fails gracefully. However if a user who is already logged in, by other means, clicks Connect to Twitter, but then hits "Cancel" on Twitter, the module raises an AttributeError
with the following stack trace:
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/erik/Documents/workspace/flask-social-example/app/middleware.py", line 16, in __call__
return self.app(environ, start_response)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask_social/views.py", line 153, in connect_callback
return connect_handler(provider.authorized_handler(connect)(), provider)
File "/Users/erik/Documents/workspace/flask-social-example/venv/lib/python2.7/site-packages/flask_social/views.py", line 120, in connect_handler
cv.setdefault('user_id', current_user.get_id())
AttributeError: 'Response' object has no attribute 'setdefault'
The issue can be raised using Flask-Social-Example with my recent bug fixes.
Lib don't allow to use factory pattern.
The connect
handler does this:
pc = request.form.get('next', allow_view)
session[config_value('POST_OAUTH_CONNECT_SESSION_KEY')] = pc
The login
handler does this:
post_login = request.form.get('next', get_post_login_redirect())
session['post_oauth_login_url'] = post_login
Ignoring any custom key set in the config. Minor, I know, but someone could eventually bump into this or something.
We've got a few PRs and issues lined up, so I figured I'd create a checklist for things we'd like for Version 1.6.3 and I can work to get them in line, onto develop
, and we can get a new version pushed to master
and pypi shortly.
@mattupstate would like to get feedback on this plan. The * items are ones that I will take care of, and I can take care of merging in portions of pull requests, if we decide.
Have you thought about adding the develop portion of
#MongoEngineConnectionDatastore
def _query(self, **kwargs):
try:
from mongoengine.queryset import Q, QCombination
except ImportError:
from mongoengine.queryset.visitor import Q, QCombination
to master as a hotfix? The current master branch is breaking since it doesn't have proper restrictions on what version of mongoengine to use.
Example traceback:
Traceback (most recent call last):
File "lost_tracker/main.py", line 63, in <module>
social = Social(app, SQLAlchemyConnectionDatastore(mdl.DB, mdl.Connection))
File "/home/exhuma/workspace/lost.lu/lost-tracker/env/lib/python3.4/site-packages/flask_social/core.py", line 106, in __init__
self._state = self.init_app(app, datastore)
File "/home/exhuma/workspace/lost.lu/lost-tracker/env/lib/python3.4/site-packages/flask_social/core.py", line 130, in init_app
config = update_recursive(module.config, config)
File "/home/exhuma/workspace/lost.lu/lost-tracker/env/lib/python3.4/site-packages/flask_social/utils.py", line 71, in update_recursive
for k, v in u.iteritems():
AttributeError: 'dict' object has no attribute 'iteritems'
Flask-OAuth is not maintained well. Try Flask-OAuthlib.
Related issue: mitsuhiko/flask-oauth#66
At least on master, I think that it's limited to the \login
route. I think the fix is using something similar to what you built for the tests in flask-security. will try to spend some time on this tomorrow.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.