pallets-eco/flask-social

Support Facebook JavaScript SDK login

Opened this issue · 5 comments

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?

There is a similar use case for an iOS app in which the auth happens in iOS and the info would be POSTed to the application. I think that this can be abstracted to handle both cases in the same way.

As far as creating a user from a social login, see this issue.

@claymation would you like to take a stab at this?

Sure. I think it involves just adding a view and maybe some customization hooks. Any ideas for the name of the view?

I was thinking we could actually do it within the existing /login and /connect views. These are already POSTs, so we could check the form for the access_token and access_secret. If they exist, skip the OAuth step, if they don't, proceed with the OAuth.

I suppose the only danger there is that if the client sends a malformed form, we'd want to raise some sort of exception rather than continue with the regular OAuth. I'd probably have to get into the weeds to really decide, but if we build it functionally enough, we should be able to merge the views later if we decide that's practical. So, yes, for now I'd stick to a new view. Maybe validated_login and validated_connect?

Given that programs (whether JavaScript, iOS, or some other native application) will be consuming these endpoints, how about something like /api/login or /login.json (and /api/connect or /connect.json)?

Since end users won't visit these endpoints directly in a browser, errors can be reported using conventional means (400 Bad Request for input errors, 500 Server Error if something goes wrong, etc), perhaps with a json response object indicating the error.

Sounds good.