omab / python-social-auth

Social auth made simple
http://psa.matiasaguirre.net
BSD 3-Clause "New" or "Revised" License
2.83k stars 1.09k forks source link

AttributeError at /complete/google-oauth2/: 'NoneType' object has no attribute 'provider' #989

Closed nitin478 closed 7 years ago

nitin478 commented 8 years ago

I am using my corporate account (which is "Google for works" account) to implement Google oauth2.0 login in to my django application.

Pipeline in "settings.py" looks like:

SOCIAL_AUTH_PIPELINE = [ 'social.pipeline.social_auth.social_details', 'social.pipeline.social_auth.social_uid', 'social.pipeline.social_auth.auth_allowed', 'social.pipeline.social_auth.associate_by_email', 'social.pipeline.social_auth.associate_user', 'social.pipeline.social_auth.load_extra_data', 'social.pipeline.user.user_details', ]

Adding conditional backends to pipepline.

if config.GCPAuthentication.AUTO_CREATE_ACCOUNTS: SOCIAL_AUTH_PIPELINE.extend([ 'social.pipeline.user.get_username', 'social.pipeline.user.create_user' ])

While trying to login for the very first time with a new user, I am getting error: AttributeError at /complete/google-oauth2/: 'NoneType' object has no attribute 'provider'

And interestingly, user is getting created and saved in DB and on next login attempt it allows me to login.

Its throwing error here : https://github.com/omab/python-social-auth/blob/master/social/actions.py#L70

My corporate Google account might not have any social account(Google+ is disabled)/related info associated with it. Is that an issue?

In any case, can you please tell me any workaround to get rid of this issue?

gabejackson commented 7 years ago

@nitin478 you resolve this issue? Experiencing the same issue with a custom OpenIDConnect backend we have implemented. But oddly only for some users. It seems that the SocialAuthUser is not being created. Will check in to it today and see what I can find out.

reeteshranjan commented 7 years ago

I have been facing this issue for quite some time and finally it seems I messed up my database. I have written a blog post https://technfoblog.wordpress.com/2016/11/30/python-social-auth-nonetype-object-has-no-attribute-provider-issue-solution/ where you can see the technical details and see if what I found solves your issue too.

gabejackson commented 7 years ago

The problem is most likely that get_user_id isn't returning the correct username. This will create a SocialAuthUser with uid = None. The next user that tries to connect will then also get this uid, which will cause the above mentioned problem. So make sure your get_user_id code is really returning a valid username for the SocialAuthUser creation part. This solved the issue for me.

reeteshranjan commented 7 years ago

In my case the uid returned by get_user_id was all fine, and for all these backends I used - linkedin, bitbucket, github, facebook, twitter and googleplus.

In pipeline/social_auth.py here is the function that uses get_user_id:

def social_uid(backend, details, response, *args, **kwargs):
    return {'uid': backend.get_user_id(details, response)}

As you'll see the next pipeline function that actually uses the uid is associate_user (in the same file). In my case, the sequence social_auth_usersocialauth_id_seq was messed up because of incorrect database dumping and reloading where I missed out setting the right value of this sequence when I ignored the corresponding SQL statement. In case you are getting this after a database dump and reload with errors like in my case, you'll find a solution in the blog link above.

Here is a quick help on debugging this including @gabejackson comments.

def associate_user(backend, uid, user=None, social=None, *args, **kwargs):
    if user and not social:
        try:
            social = backend.strategy.storage.user.create_social_auth(
                user, uid, backend.name
            )
        except Exception as err:
            # Added trace here - Reetesh
            traceback.print_exc()
            if not backend.strategy.storage.is_integrity_error(err):
                raise
            # Protect for possible race condition, those bastard with FTL
            # clicking capabilities, check issue #131:
            #   https://github.com/omab/django-social-auth/issues/131
            # Added trace here - Reetesh
            traceback.print_exc()
            return social_user(backend, uid, user, *args, **kwargs)
        else:
            return {'social': social,
                    'user': social.user,
                    'new_association': True}

NOTE: You'd need to add import traceback for the above to work.

In my case, where the uid was fine, I hit the integrity error and the 2nd traceback.print_exc() was executed (as you can see any integrity errors are not raised again). If you get the same issue, then you can follow the blog link in my above comment to see the problem and solution.