Django - Social_Auth - Facebook Logout - NotAllowedToDisconnect - django

I have used django package social_auth to implement facebook login on my website. I am able to log in correctly and get all the data. But I am not able to logout.
I am not using django.user.login and logout. I am using socialauth_begin and socialauth_disconnect
I am able to login, go in the social auth pipeline, get the necessary information, but I am not able to logout. What is the fix to this problem?
When I click on "Logout" in Logout
I get the following error
NotAllowedToDisconnect at /tomonotomo/auth/disconnect/facebook/
No exception supplied
Request Method: GET
Request URL: http://localhost:8000/tomonotomo/auth/disconnect/facebook/
Django Version: 1.5.1
Exception Type: NotAllowedToDisconnect
Exception Location: /tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/local/lib/python2.7/site-packages/social_auth/backends/__init__.py in disconnect, line 435
Python Executable: /tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/bin/python2.7
Python Version: 2.7.3
Python Path:
['/tmp/guest-onyOH9/pratik/tomonotomo_project',
'/tmp/guest-onyOH9/Desktop/pycharm-2.7.3/helpers/pydev',
'/tmp/guest-onyOH9/pratik/tomonotomo_project',
'/tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/lib/python2.7',
'/tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/lib/python2.7/plat-linux2',
'/tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/lib/python2.7/lib-tk',
'/tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/lib/python2.7/lib-old',
'/tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/lib/python2.7/lib-dynload',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk',
'/tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/local/lib/python2.7/site-packages',
'/tmp/guest-onyOH9/pratik/virtualenv-1.10/tomonotomo/lib/python2.7/site-packages']
Server time: Sat, 10 Aug 2013 22:27:42 -0500
The settings I have is this:
AUTHENTICATION_BACKENDS = (
'social_auth.backends.facebook.FacebookBackend',
'django.contrib.auth.backends.ModelBackend',
)
FACEBOOK_EXTENDED_PERMISSIONS= ['email', 'user_birthday']
SOCIAL_AUTH_PIPELINE = (
'social_auth.backends.pipeline.social.social_auth_user',
'social_auth.backends.pipeline.associate.associate_by_email',
'social_auth.backends.pipeline.user.get_username',
'social_auth.backends.pipeline.user.create_user',
'tomonotomo.social_auth_pipeline.create_custom_user',
'social_auth.backends.pipeline.social.associate_user',
'social_auth.backends.pipeline.user.update_user_details',
)
SOCIAL_AUTH_CREATE_USERS = True
SOCIAL_AUTH_FORCE_RANDOM_USERNAME = False
SOCIAL_AUTH_DEFAULT_USERNAME = 'socialauth_user'
SOCIAL_AUTH_ENABLED_BACKENDS = ('facebook',)
SOCIAL_AUTH_COMPLETE_URL_NAME = 'socialauth_complete'
SOCIAL_AUTH_ASSOCIATE_URL_NAME = 'socialauth_associate_complete'
SOCIAL_AUTH_ASSOCIATE_BY_EMAIL = True
SOCIAL_AUTH_ERROR_KEY = 'socialauth_error'
SOCIAL_AUTH_REDIRECT_IS_HTTPS = False
LOGIN_URL = '/tomonotomo/login/'
LOGIN_REDIRECT_URL = '/tomonotomo/'
LOGIN_ERROR_URL = '/tomonotomo/login-error/'
Please Help. Thanks
The code I used to Login was:
<h3 style="color:white">Connect via Facebook</h3>

I just have the same problem but with twitter.
This error is generated because the user has not another way to connect/disconnect from the system, and the API in some way think it would be dangerous.
How I resolve the problem was calling a custom logout form like in the example:
https://github.com/omab/django-social-auth/blob/master/example/app/views.py#L39

Related

Django Azure AD Integration

I'm currently integrating SSO using Azure AD for a Django Project. I'm currently using the package: https://github.com/leibowitz/django-azure-ad-auth . I have followed the docs to setup the Azure AD Authentication . On entering the application url, it takes me to the microsoft login page and after entering the credentials it's redirected to the application. But on redirection to the application after the Azure Auth, the code checks in the session for 'nonce' & 'state' variables , which are strangely returned as None and hence the application redirects to the failure url.
#never_cache
def auth(request):
backend = AzureActiveDirectoryBackend()
redirect_uri = request.build_absolute_uri(reverse(complete))
nonce = str(uuid.uuid4())
request.session['nonce'] = nonce
state = str(uuid.uuid4())
request.session['state'] = state
login_url = backend.login_url(
redirect_uri=redirect_uri,
nonce=nonce,
state=state
)
return HttpResponseRedirect(login_url)
#never_cache
#csrf_exempt
def complete(request):
backend = AzureActiveDirectoryBackend()
method = 'GET' if backend.RESPONSE_MODE == 'fragment' else 'POST'
original_state = request.session.get('state')
state = getattr(request, method).get('state')
if original_state == state:
token = getattr(request, method).get('id_token')
nonce = request.session.get('nonce')
user = backend.authenticate(token=token, nonce=nonce)
if user is not None:
login(request, user)
return HttpResponseRedirect(get_login_success_url(request))
return HttpResponseRedirect('failure')
This is the code used for authentication.
Settings.py sample is given below:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'azure_ad_auth.backends.AzureActiveDirectoryBackend',
)
LOGIN_REDIRECT_URL = '/login_successful/'
AAD_TENANT_ID = 'd472b4f4-95c5-4eb3-8a9a-3615c837eada'
AAD_CLIENT_ID = '75e38b53-8174-4dc6-a8f6-bb7a913f1565'
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_SAVE_EVERY_REQUEST = True
SESSION_COOKIE_AGE = 86400 # sec
SESSION_COOKIE_DOMAIN = None
SESSION_COOKIE_NAME = 'DSESSIONID'
SESSION_COOKIE_SECURE = True
Traceback
TypeError at /TypeError at /project/azure/complete/
must be str, not NoneType
Request Method: POST
Request URL: http://testdomain.com/project/azure/complete/
Django Version: 2.2.4
Exception Type: TypeError
Exception Value:
must be str, not NoneType
Exception Location: /home/project/azure_auth/views.py in complete, line 57
Python Executable: /home/project/app/venv/bin/python3
Python Version: 3.6.8
Python Path:
['/home/project/app/project',
'/home/project/app/venv/bin',
'/home/project/app/venv/lib64/python36.zip',
'/home/project/app/venv/lib64/python3.6',
'/home/project/app/venv/lib64/python3.6/lib-dynload',
'/usr/lib64/python3.6',
'/usr/lib/python3.6',
'/home/project/app/venv/lib/python3.6/site-packages']
Server time: Tue, 19 Nov 2019 05:21:10 +0000/azure/complete/
must be str, not NoneType
Request Method: POST
Request URL: http://testdomain.com/project/azure/complete/
Django Version: 2.2.4
Exception Type: TypeError
Exception Value:
must be str, not NoneType
Exception Location: /home/project/app/project/azure_auth/views.py in complete, line 57
Python Executable: /home/project/app/venv/bin/python3
Python Version: 3.6.8
Python Path:
['/home/project/app/project',
'/home/project/app/venv/bin',
'/home/project/app/venv/lib64/python36.zip',
'/home/project/app/venv/lib64/python3.6',
'/home/project/app/venv/lib64/python3.6/lib-dynload',
'/usr/lib64/python3.6',
'/usr/lib/python3.6',
'/home/project/app/venv/lib/python3.6/site-packages']
Server time: Tue, 19 Nov 2019 05:21:10 +0000
/home/project/app/project/azure_auth/views.py in complete
f.write("nonce -->"+nonce+"\n") …
▼ Local vars
Variable Value
backend
<azure_auth.backends.AzureActiveDirectoryBackend object at 0x7f5c688dce80>
data
['82aff4f9-2cc0-4521-aea7-ad3281d20774\n',
'ba821364-86c9-4233-881f-bdc772f7c488\n']
f
<_io.TextIOWrapper name='t1.txt' mode='w' encoding='UTF-8'>
method
'POST'
n
'82aff4f9-2cc0-4521-aea7-ad3281d20774'
nonce
None
original_state
None
request
<WSGIRequest: POST '/project/azure/complete/'>
state
'fd93da6a-9009-4363-9640-9364df7f64df'
token
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkJCOENlRlZxeWFHckdOdWVoSklpTDRkZmp6dyIsImtpZCI6IkJCOENlRlZxeWFHckdOdWVoSklpTDRkZmp6dyJ9.eyJhdWQiOiI0MDMyODJjZi1kYjlmLTQ1OTYtOWM1My0wMmI1MTA2ZDA0MDIiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9mYmM0OTNhOC0wZDI0LTQ0NTQtYTgxNS1mNGNhNThlOGMwOWQvIiwiaWF0IjoxNTc0MTQwNTY5LCJuYmYiOjE1NzQxNDA1NjksImV4cCI6MTU3NDE0NDQ2OSwiYWlvIjoiNDJWZ1lCQSt4TFhqNEdVTjRRWEJiU3ZOZmF4NXBHY2NPenFoNzFuNDlXMmxnYTYzMjIwQiIsImFtciI6WyJwd2QiXSwiZmFtaWx5X25hbWUiOiJFIEsgUyIsImdpdmVuX25hbWUiOiJTdXNyZWV0aGEiLCJpbl9jb3JwIjoidHJ1ZSIsImlwYWRkciI6IjE4Mi43NS4xNjcuMTg4IiwibmFtZSI6IkUgSyBTLFN1c3JlZXRoYSIsIm5vbmNlIjoiODgyNTg4ZjgtMGM3MC00Y2JlLTk4MTktY2JkNjUyZmI0MDQ5Iiwib2lkIjoiNTU0ZjYzZWEtOTg4Yi00MmMwLTk4NjUtMTIxMDNkZTdhZTBmIiwib25wcmVtX3NpZCI6IlMtMS01LTIxLTYwMzE5MzI1LTExNjA5ODI5NTEtMTYwMTc3MzkwNy02NTg1OTMiLCJzdWIiOiI2aERUa1hYYkN3Wm5rcHEwSU9wRTRVWk56RHZlRFhvVjM3RGV5U3dkaDZRIiwidGlkIjoiZmJjNDkzYTgtMGQyNC00NDU0LWE4MTUtZjRjYTU4ZThjMDlkIiwidW5pcXVlX25hbWUiOiJTRTA3NTA0OEBjZXJuZXIubmV0IiwidXBuIjoiU0UwNzUwNDhAY2VybmVyLm5ldCIsInV0aSI6IkZTQmhnVDg4UTAyUHNfU293ZDdtQUEiLCJ2ZXIiOiIxLjAifQ.Rvc6xcPRZ01iebYtEyAWeyDnQEUVtqV1L1mapr658jLog-_yIASyEm3kMrkt6dIWWEO3dJSe3k05xOJlbnHqcjaR5LKAwOZzGR_oBmyIyB8-IvuEankNVpwYtcz8mY7kFr6AqQmIsx7xLLgv4grp-bSy4eRqjk36VeLX_LwMBuM_U6V70w0gXN1vvFCj0tjsv-VtTAmNgvdxS0ltzdD3rzZ87DoXbPWmoozLtO9WBRsJvMuvn-frBtYUYkIhs3I-eVAO9ZG2IWEuLQx6k7RBmzX6HgFi9SVpyEhNru7fmwO-qj5uRj9FQa45lCZluUV25o_AV1NQ94d5lnFyeMh7uw'
user
None
I got the above error while trying to write the session variables to file (for debugging.)
I know this question is a bit old, but the session won't be able to be retrieved (and with it the original state and nonce), and will fail the comparison if the cookie is not being sent by the browser.
The cookie is not sent by default in django 2.1+, since the default settings add SameSite=Lax
The cookies used for django.contrib.sessions, django.contrib.messages,
and Django’s CSRF protection now set the SameSite flag to Lax by
default. Browsers that respect this flag won’t send these cookies on
cross-origin requests. If you rely on the old behavior, set the
SESSION_COOKIE_SAMESITE and/or CSRF_COOKIE_SAMESITE setting to None.
https://docs.djangoproject.com/en/3.0/releases/2.1/#samesite-cookies
In theory this should still send the cookie (from what I understand), but for some reason chrome doesn't seem to. There's something I clearly do not understand, so if anyone knows better please comment.
Anyway, changing the setting via SESSION_COOKIE_SAMESITE = None should work.

Django 1.11 on passenger_wsgi not routing POST request

I'm trying to setup python on A2 shared hosting via passenger_wsgi.
The app is working fine when I run it via 'runserver'. I tested this both in my local PC, and via SSH tunnel.
However, when I try to set this up on passenger_wsgi, it can't seem to be able to route POST request.
1 import os
2 import sys
3
4 sys.path.insert(0, "/home/<username>/app")
5
6 import APP_CORE
7
8 # where is the python interpreter
9 INTERP = "/home/<username>/app/.virtualenv/bin/python"
10 if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv)
11
12
13 os.environ['DJANGO_SETTINGS_MODULE'] = "APP_CORE.settings"
14
15 import APP_CORE.wsgi
16 application = APP_CORE.wsgi.application
Example: when I load the admin page (/admin/login), it can load the login page, but when submitting the credentials, it says that POST to /admin/login is not found - returning HTTP 404.
The SAME flow when I run via runserver works - I feel that I could be missing something in the django WSGI configuration. Any help would be appreciated !!
Edit/update: After diving into resolver.py and base.py:_get_response, I've noticed that somehow the /path/info truncates the first bit of the URL. Example, when I am requesting for /admin/login/, the path info only shows /login - but when I am using runserver, it is properly passed thru as /admin/login. To me this is clearly the issue on the web server setup and not on the django site. So will try to work it out with A2Hosting...
It looks like you may have solved this, but to followup for anyone that may stumble here. I have been using A2Hosting, Passenger, and CPanel with django (and wagtail). What I found was that during POST requests the wsgi SCRIPT_NAME was being set to a relative path and not the root of the application.
When I added logging to each application call, the correct GET request was:
{
'REQUEST_URI': '/admin/',
'PATH_INFO': '/admin/',
'SCRIPT_NAME': '',
'QUERY_STRING': '',
'REQUEST_METHOD': 'GET',
...
But on that page, a form was submitting a POST, which had the PATH_INFO incorrectly set:
{
'REQUEST_URI': '/admin/login/',
'PATH_INFO': '/login/',
'SCRIPT_NAME': '/admin',
'QUERY_STRING': '',
'REQUEST_METHOD': 'POST',
...
The workaround I ended up using was to create middleware which asserted a known SCRIPT_NAME and rebuilt the PATH_INFO from it.
# Set this to your root
SCRIPT_NAME = ''
class PassengerPathInfoFix(object):
"""
Sets PATH_INFO from REQUEST_URI since Passenger doesn't provide it.
"""
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
from urllib.parse import unquote
environ['SCRIPT_NAME'] = SCRIPT_NAME
request_uri = unquote(environ['REQUEST_URI'])
script_name = unquote(environ.get('SCRIPT_NAME', ''))
offset = request_uri.startswith(script_name) and len(environ['SCRIPT_NAME']) or 0
environ['PATH_INFO'] = request_uri[offset:].split('?', 1)[0]
return self.app(environ, start_response)
application = get_wsgi_application()
application = PassengerPathInfoFix(application)
Related Reading:
http://alyalearningdjango.blogspot.com/2014/05/issue-360-passenger-doesnt-set-pathinfo.html
https://github.com/phusion/passenger/issues/460
https://www.python.org/dev/peps/pep-0333/#environ-variables

Django 2.0 allauth Facebook 2018

I got Twitter and Google login with Django all-auth.
Having issues with Facebook now.
Tried every single combination between localhost/127.0.0.1/etc (also went extreme routes by changing my hosts to local.domain.com - even got an SSL thing going as Facebook apparently blocks http access (since March 2018).
Got this far... now I get this error
Can anyone lead me into the right direction?
I'm about to pull my hair out.
KeyError at /accounts/facebook/login/token/ 'access_token' Request Method: POST Request
URL: https://localhost:8000/accounts/facebook/login/token/ Django
Version: 2.0.3 Exception Type: KeyError Exception Value:
'access_token'
{'error': {'code': 5,
'fbtrace_id': 'Bs4PHOvc+rZ',
'message': "This IP can't make requests for that application.",
'type': 'OAuthException'}}
Addition details:
http://localhost:8000/accounts/facebook/login/callback
SOCIALACCOUNT_PROVIDERS = {
'facebook': {
'METHOD': 'js_sdk',
'SCOPE': ['email', 'public_profile', 'user_friends'],
'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
'INIT_PARAMS': {'cookie': True},
'FIELDS': [
'id',
'email',
'name',
'first_name',
'last_name',
'verified',
'locale',
'timezone',
'link',
'gender',
'updated_time',
],
'LOCALE_FUNC': lambda request: 'en_GB',
'EXCHANGE_TOKEN': True,
'VERIFIED_EMAIL': False,
'VERSION': 'v2.5',
}
}
Django 1.4.15, django-allauth 0.18.0, Facebook upgrade API v2.8
Since Mars 2018, Facebook sets "Use Strict Mode for Redirect URls" YES by default. My problem was in the Facebook App configuration, not in django-allauth.
Working again App settings:
Settings Basic
- App Domains: "AnySite.com"
- Privacy policy URL: "https://AnySite.com/myprivacy/"
- Website: "https://AnySite.com/"
Settings Advanced
- Server IP Whitelist: let it blank
- Domain Manager: let it blank
Facebook login Settings
Yes Client OAuth Login
Yes Web OAuth Login
Yes (new: forced) Use strict Mode for redicect URLs
Yes Embeded Browser OAuth Login
Yes Enforce HTTPS
Valid OAuth Redirect URLs: "https://AnySite.com/accounts/facebook/login/callback/" (mandatory)
Hope it helps.
Update in case anyone else is struggling with this in 2020:
In facebook developers:
create a test app from your main app
settings -> basic, add localhost and 127.0.0.1 to app domains. set site url to https://localhost:8000
Products -> facebook login -> settings. client, wen login enabled. Embedded Browser OAuth Login enabled.
Add all of these into Valid OAuth Redirect URIs:
https://127.0.0.1:8000/
https://127.0.0.1:8000/accounts/facebook/login/callback
https://localhost:8000/
https://localhost:8000/accounts/facebook/login/callback
In django:
pip install django-sslserver
add sslserver to INSTALLED_APPS
python manage.py runsslserver
In admin:
Create 2 sites, https://127.0.0.1:8000/ and https://localhost:8000/
Add a social application, facebook, add in your test app id and key. Register the 2 sites above into it.

Facebook authentication using angular JS and Django

I'm a beginner in both angular JS and django. I was following this particular tutorial in making a facebook authentication app.
http://cbdev.blogspot.in/2014/02/facebook-login-with-angularjs-django.html
I've followed the tutorial exactly. And when I start the server I get the error.
NameError at /
name 'strategy' is not defined
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 1.3.1
Exception Type: NameError
Exception Value:
name 'strategy' is not defined
Exception Location: /root/Documents/django/clueless/clueless_engine/../clueless_engine/views.py in <module>, line 1
Python Executable: /root/Documents/django/clueless/bin/python
Python Version: 2.7.13
Python Path:
['/root/Documents/django/clueless/clueless_engine',
'/root/Documents/django/clueless/lib/python2.7',
'/root/Documents/django/clueless/lib/python2.7/plat-x86_64-linux-gnu',
'/root/Documents/django/clueless/lib/python2.7/lib-tk',
'/root/Documents/django/clueless/lib/python2.7/lib-old',
'/root/Documents/django/clueless/lib/python2.7/lib-dynload',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/root/Documents/django/clueless/local/lib/python2.7/site-packages',
'/root/Documents/django/clueless/lib/python2.7/site-packages']
Server time: Thu, 1 Jun 2017 07:30:14 +0530
my views.py file is
#strategy()
def auth_by_token(request, backend):
backend = request.strategy.backend
user=request.user
user = backend.do_auth(
access_token=request.DATA.get('access_token'),
user=user.is_authenticated() and user or None
)
if user and user.is_active:
return user# Return anything that makes sense here
else:
return None
#csrf_exempt
#api_view(['POST'])
#permission_classes((permissions.AllowAny,))
def social_register(request):
auth_token = request.DATA.get('access_token', None)
backend = request.DATA.get('backend', None)
if auth_token and backend:
try:
user = auth_by_token(request, backend)
except Exception, err:
return Response(str(err), status=400)
if user:
strategy = load_strategy(request=request, backend=backend)
_do_login(strategy, user)
return Response( "User logged in", status=status.HTTP_200_OK )
else:
return Response("Bad Credentials", status=403)
else:
return Response("Bad request", status=400)
I have created Social Auth authentication using python scocial auth. you can check:
https://github.com/ranvijay-sachan/django-rest-login-and-social_auth/tree/master/profiles
POST: http://localhost:8000/api/v1/login/2/
Content-Type : application/json
{ "accessToken": "alert token" }
The problem was that I forgot to import modules.
from social.apps.django_app.utils import load_strategy strategy = load_strategy(request)

django-allauth with SSL : "DoesNotExist at /accounts/google/login/callback/"

I'm testing my django (1.6.5) app in localhost. I use django-allauth and without ssl everything was ok.
I installed django-sslserver and change as follows:
Settings.py
ACCOUNT_DEFAULT_HTTP_PROTOCOL = 'https' # allauth
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
os.environ['HTTPS'] = "on"
Api Google Console
REDIRECT URIS : http://localhost:8000/accounts/google/login/callback/
https://localhost:8000/accounts/google/login/callback/
When I logged in with my google account, I accepted the authorization, but when it's redirected back to my app, shows the error:
DoesNotExist at /accounts/google/login/callback/
User matching query does not exist.
Request URL: https://localhost:8000/accounts/google/login/callback/?state=PwKj3DsvzmNp&code=4/16ttwvGn7SIZKyHWZ9sSy8YOx7sg.4t9M4AcGcoEfoiIBeO6P2m9E6KmpkAI
allauth/socialaccount/helpers.py in _login_social_account
def _login_social_account(request, sociallogin):
**return perform_login(request, sociallogin.account.user, ...**
email_verification=app_settings.EMAIL_VERIFICATION,
redirect_url=sociallogin.get_redirect_url(request),
signal_kwargs={"sociallogin": sociallogin})
The error is in the return line.
Can you help me? Thanks! :)