6

I am using Django 1.10 with python 2.7 and social-auth-app-django (1.2.0). It is part of the Python Social Auth library.

I wish to restrict login to only the domain ID of my company I've therefore used this setting from the library.

SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS=['mycompany.in']

Now if you try to login with any other domain as expected it throws an error.

My goal is to catch this exception and show a custom page to the user. But for the life of me I am unable to do so.

If I set Debug to False it redirects the user to my

LOGIN_ERROR_URL='/'

page but am unable to pass my custom message to the user

This is part of my setting.py

DEBUG = False

    MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'social_django.middleware.SocialAuthExceptionMiddleware',
]

#social auth
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY= "9******6.apps.googleusercontent.com"
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET="W*****x"
SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS=['mycompany.in']
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'upload_file'
LOGOUT_URL = 'logout'
LOGIN_ERROR_URL='logout

In my view I've this code to handle the exception

from social_django.middleware import SocialAuthExceptionMiddleware
from social_core.exceptions import AuthForbidden


    class SocialAuthExceptionMiddleware(SocialAuthExceptionMiddleware):
      def process_exception(self, request, exception):
        print "exception occured"
        if hasattr(social_exceptions, 'AuthForbidden'):
          print "hello two"
          return HttpResponse("I'm a exception %s" % exception)
        else:
          print "other exception"
          raise exception

I've even tried with

def process_template_response(self):
    print "response"'

def get_redirect_uri(request, exception):
    print "URL"

But to no avail.

I've followed these link python-social-auth AuthCanceled exception

and

http://python-social-auth-docs.readthedocs.io/en/latest/configuration/django.html#exceptions-middleware

This is the output when debug is set to False:

"AuthForbidden at /app/oauth/complete/google-oauth2/ Your credentials aren't allowed"

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
Shaikh Saleem
  • 75
  • 1
  • 6

1 Answers1

5
  1. Need to set value for SOCIAL_AUTH_LOGIN_ERROR_URL in settings.py
  2. Extend SocialAuthExceptionMiddleware class & need to overwrite the "get_message" method
  3. Handle error URL display the message to user.

For example

Middleware.py

from social_django.middleware import SocialAuthExceptionMiddleware

class CustomSocialAuthExceptionMiddleware(SocialAuthExceptionMiddleware):
    def get_message(self, request, exception):
       default_msg = super(CustomSocialAuthExceptionMiddleware).get_message(request, exception) # in case of display default message
       return "Custom messages text write here."

settings.py

SOCIAL_AUTH_LOGIN_ERROR_URL = '/error_page/'
MIDDLEWARE = [
'...',
'path.to.custom.middleware.CustomSocialAuthExceptionMiddleware',
]

URL.py

from django.conf.urls import url

from views import ErrorPage

urlpatterns = [
    url(r'^error_page/$', ErrorPage.as_view(), name="error-page"),
]

view.py

from django.views.generic.base import TemplateView

class ErrorPage(TemplateView):
    template_name = 'error.html'

error.html(template)

....
   <body>
     {% if messages %}
        <ul class="messages">
           {% for message in messages %}
               <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }} </li>
        {% endfor %}
        </ul>
    {% endif %}
   </body>
....

If you are using django message framework. In case of not using django message framework, Middleware add message into GET parameter which you can display on error page.

Kaushal
  • 666
  • 6
  • 15
  • Hi, Thank you for the answer. But it seems to work only partially. I've followed the instructions perfectly, the print statement that I've added inside the overloaded method executes so the control goes inside the method but then the redirections fails `(SOCIAL_AUTH_LOGIN_ERROR_URL="error-page")` . Instead I receive a 'Server Error (500)' However if I remove the middleware then the redirection works. But then I do not have the overloaded method. – Shaikh Saleem Jun 12 '17 at 08:15
  • Okay, so I was able to make this work after removing the statement `default_msg = super(CustomSocialAuthExceptionMiddleware).get_message(request, exception) ` Not sure what the issue was with the statement @kaushal , can you pls explain the reason for the failure of this particular statement ? Error received was `Server Error (500)` – Shaikh Saleem Jun 12 '17 at 09:08
  • @ShaikhSaleem Server Error (500) is very generic error. It very hard to know which statement cause error. Please look at traceback.(In local development make sure debug=True in settings.py to view full trackback otherwise it's only show server error (500) ) You may get clue. – Kaushal Jun 17 '17 at 09:44