sns-sdks / python-facebook

A simple Python wrapper for facebook graph api :sparkles: :cake: :sparkles: .
https://sns-sdks.github.io/python-facebook/
328 stars 86 forks source link

login process with django framework in multiple views has Session error #209

Closed SebaRGFSL closed 1 year ago

SebaRGFSL commented 2 years ago

I'm trying to use the library to generate a login process for a django app for both FB and IG. I manage to get the auth URL and redirect the user to FB login and Ig login successfully in one view. Then I set another view to handle FB and IG redirection after the user put the login credentials. In this second view I have to instantiate again the GraphAPI to execute the exchange_user_access_token method but I get an error with the session since the CSRF is not the same as the first instance. How can I solve this issue to completely handle the login with the wrapper (I worked around this issue by fulfilling the access token fetch with requests). Here are the pieces of code:

def social_account_login(request):
    social_account_parameter = request.GET.get('social_account')
    #FB case
    if social_account_parameter == 'FB':
        redirect_uri = 'https://testurl.com' + reverse('return_fb_login')
        api = GraphAPI(app_id = settings.FB_APP_ID, app_secret = settings.FB_APP_SECRET, oauth_flow = True)
        auth_url = api.get_authorization_url(redirect_uri = redirect_uri, scope = ['pages_show_list'])

        return redirect(auth_url[0])
    #If there's an invalid parameter return error
    else:
        return JsonResponse({'Error': f'Social account parameter {social_account_parameter} not valid'})

after FB login:

def return_fb_login(request):

    response_uri = 'https://testurl.com' + reverse('return_fb_login') + '?code=' + request.GET['code']
    api = GraphAPI(app_id = settings.FB_APP_ID, app_secret = settings.FB_APP_SECRET, application_only_auth = True)
    token = api.exchange_user_access_token(response = response_uri)
    return JsonResponse(token, safe = False)
MerleLiuKun commented 2 years ago

I can give you an example for this. you can give a try.

To get authorize url

from pyfacebook import GraphAPI

redirect_uri = "https://localhost/"

api = GraphAPI(app_id="app id", app_secret="app secret", oauth_flow=True)

api.get_authorization_url(redirect_uri=redirect_uri)
# https://xxxxxxx

Then exchange the access token

api2 = GraphAPI(app_id="app id", app_secret="app secret", oauth_flow=True)

api2.exchange_user_access_token(response="https://xxxx", redirect_uri=redirect_uri)
# {"access_token": "xxxxx"}

just make the graph api instance initial with the same parameters.

SebaRGFSL commented 2 years ago

I'm doing exactly that, even with the oauth_flow = True but I get the following error:

image
lucas-montes commented 1 year ago

I'm doing exactly that, even with the oauth_flow = True but I get the following error: image

I have the same issue. Did you manage to fix it?

MerleLiuKun commented 1 year ago

I will check this again quickly.

MerleLiuKun commented 1 year ago

Hi,

Just as the errors says. You not have the state parameter.

So your code in function return_fb_login

response_uri = 'https://testurl.com' + reverse('return_fb_login') + '?code=' + request.GET['code']

Need change to

response_uri = 'https://testurl.com' + reverse('return_fb_login') + '?code=' + request.GET['code']+ "&state=" + request.GET['state']

And

token = api.exchange_user_access_token(response = response_uri)

Need change to

redirect_uri = settings.DOMAIN_URL + reverse('return_fb_login')
token = api.exchange_user_access_token(response=response_uri, redirect_uri=redirect_uri)

Then, the oauth will success!

lucas-montes commented 1 year ago

Hi,

Just as the errors says. You not have the state parameter.

So your code in function return_fb_login

response_uri = 'https://testurl.com' + reverse('return_fb_login') + '?code=' + request.GET['code']

Need change to

response_uri = 'https://testurl.com' + reverse('return_fb_login') + '?code=' + request.GET['code']+ "&state=" + request.GET['state']

And

token = api.exchange_user_access_token(response = response_uri)

Need change to

redirect_uri = settings.DOMAIN_URL + reverse('return_fb_login')
token = api.exchange_user_access_token(response=response_uri, redirect_uri=redirect_uri)

Then, the oauth will success!

Yep you're right. Thanks.