st4lk / django-rest-social-auth

OAuth signin with django rest framework
MIT License
522 stars 122 forks source link

email is missing #24

Open deniskkotov opened 8 years ago

deniskkotov commented 8 years ago

I use email as USERNAME_FIELD in my custom User model, and I need email in my pipelines. But in my pipelines I get only this information

{ 'username': u'DenisKotov', 'fullname': u'Denis Kotov', 'last_name': u'Kotov', 'email': '', 'first_name': u'Kotov' } I have set SOCIAL_AUTH_FACEBOOK_SCOPE = ['email', ] in my settings

What am I doing wrong?

aabmass commented 8 years ago

I was also getting this issue, but it seems to be working fine in the sample app.

deniskkotov commented 8 years ago

I tested this moment in test project and also got this issue

aabmass commented 8 years ago

I just tested it too, but it worked fine for me. Not sure then.

st4lk commented 8 years ago

Haven't looked at the code yet, but there is possibility that facebook will not return email. From https://developers.facebook.com/docs/facebook-login/permissions#reference-email:

Note, even if you request the email permission it is not guaranteed you will get an email address. For example, if someone signed up for Facebook with a phone number instead of an email address, the email field may be empty.

deniskkotov commented 8 years ago

Hmm.. Maybe you are right, but I have been tested this with my own account. And I use email for login in Facebook. Can you tell me, where and how I can see Facebook's answer? Or maybe Facebook has service for testing this?

st4lk commented 8 years ago

Here how you can see the facebook answer. First, set logging to log everything. To do it, add following logger to LOGGING['loggers'] in your settings.py:

'': {
    'handlers': ['console', ],
    'level': "DEBUG",
},

So total LOGGING can look like this:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        '': {
            'handlers': ['console', ],
            'level': "DEBUG",
        },
        'rest_social_auth': {
            'handlers': ['console', ],
            'level': "DEBUG",
        },
    }
}

Then try to login via facebook. In console you should see the requests, that were made. You need to find this request:

 "GET /v2.3/me?access_token=123abc... HTTP/1.1" 200 232

Then just call it in browser and see the response from facebook:

https://graph.facebook.com/v2.3/me?access_token=123abc...

st4lk commented 8 years ago

Also you can find access_token in admin (if you enable it).

Or from shell

user = YourUserModel.objects.get()  # apply corresponding filter here to get particular user
print(user.social_auth.filter(provider='facebook')[0].access_token)

Then put this access_token in url https://graph.facebook.com/v2.3/me?access_token=your_access_token

st4lk commented 8 years ago

@deniskkotov , does it help?

deniskkotov commented 8 years ago

yep, I solved this with adding 'email' into SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS['fields'] in django settings.

But I have new problem, how I can get some optional info? for example 'birthdate' or 'location'? should I get some permissions before getting oauth code?

st4lk commented 8 years ago

As it turns out, in our way of authorisation (using JS client and REST api) we need to define scope at front-end side. Looks like in our case the setting SOCIAL_AUTH_FACEBOOK_SCOPE doesn't make sense, since first request is made by front-end. I guess it must be mentioned in readme.

I've made an example in branch issue/24. The only difference is file home_session.html, where i defined scope at front-end level. I've added 'user_birthday' permission. Also, pay attention, that i set 'email' permission explicitly. As i understand, email permission is included in default 'public profile' of facebook, but maybe it is better to define it explicitly at your front-end side.

After i confirmed the log-in i could get birthday from facebook graph api. But keep in mind, that 'user_birthday' permission is not included in normal facebook permission. Normal permissions are: public_profile, email and user_friends. More than that permissions requires facebook review. Details here.

Nevertheless, i tried to login with permission 'user_birthday' set at front-end side (look branch issue/24). I just see the warning at login page:

Facebook login with birthday warning

But when i confirm, i can get birthday from graph api:

Facebook birthday graph api

st4lk commented 8 years ago

Full list of facebook permissions can be found here.

ghost commented 7 years ago

Had same problem - now at autumn 2017. Seems like at least v2.8 of FB graph endpoint /me (which is used by python-social-auth facebook backend to get user info) now explicitly require to set "fields" you want to get from user. And email is just not sent by default, though you CAN get it. https://stackoverflow.com/a/41715637

To actually get email you can to utilize this var (python social already CAN send additional params to /me request) to force getting that fields: SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {'fields': 'email,first_name,last_name'}

Another example but in case of using Facebook SDK. So this is "new rules" problem. Maybe just need to update readme for people - that SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS is no longer optional but required is case you need email.

Here one can find all other fields.

statico commented 6 years ago

FWIW, I was trying to debug something similar and found that I was sending the scope parameter at the wrong time. It's also amusing that I took similar screenshots as @st4lk - https://github.com/jaredhanson/passport-facebook/issues/214#issuecomment-348659884