Python Django

Updated May 5th 2018

Tested with Python 2 Version 2.7.14 along with Django version 1.11.12 Tested with Python 3 Version 3.6.5 along with Django version 2.0.4

Python Social Auth with PixelPin

Step-by-step installation guide

Python Social Auth is an easy to setup social authentication/registration mechanism with support for several frameworks and auth providers, including PixelPin.

To complete the installation, you'll need to create your PixelPin developer account.

Download the example website

Downloading an example website allows you to understand how to install PixelPin Auth OpenID Connect into a Python Django website. The knowledge you'll learn from installing the module will allow you to install the module onto your own website.

Before starting the installation guide, you'll need the example website from our GitHub page found here.

Installation

    First in your favourite CLI install the following packages:

    pip install social-auth-app-django social-auth-core[openidconnect]
    

Configuring the module

  1. Go to /mysite/settings.py.

  2. Add the following string:

    'social_django'
    

    To the INSTALLED_APPS array as shown below:

  3. Add the following string:

    'social_django.middleware.SocialAuthExceptionMiddleware'
    

    into the MIDDLEWARE array as shown below: (MIDDLEWARE_CLASSES for Django version 1.9 and below)

  4. Add the following strings:

    'social_django.context_processors.backends',
    'social_django.context_processors.login_redirect'
    

    into the context_processors array which is located in the TEMPLATES array as shown below:

  5. Add the following string:

    'mysite.backends.pixelpin.PixelPinOpenIDConnect'
    

    into the AUTHENTICATION_BACKENDS as shown below:

  6. Towards the bottom of settings.py add the following variables:

    SOCIAL_AUTH_PIXELPIN_OPENIDCONNECT_KEY = '-Your-Client-ID-'
    SOCIAL_AUTH_PIXELPIN_OPENIDCONNECT_SECRET = '-Your-Client-Secret-'
    
    SOCIAL_AUTH_LOGIN_ERROR_URL = '/profile/'
    #This is where you configure where the user ends up after authentication
    SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/profile/'
    SOCIAL_AUTH_RAISE_EXCEPTIONS = False
    
  7. Next you'll need to create a PixelPin developer account to retrieve your PixelPin Client ID and Client Secret. To create a PixelPin developer account you'll need your Redirect URI. Your Redirect URI will be, for example: http(s)://www.example.co.uk/complete/pixelpin-openidconnect. If you haven't created a PixelPin developer account before, a guide can be found here to guide you through the steps to create a PixelPin developer account.

  8. Once you've created your PixelPin developer account, copy and paste the Client ID and Client Secret into the SOCIAL_AUTH_PIXELPIN_OPENIDCONNECT_KEY and SOCIAL_AUTH_PIXELPIN_OPENIDCONNECT_SECRET variables respectively.

  9. Next we're going to add the PixelPin backend. In mysite/backends create a file called pixelpin.py and copy and paste the following code:

    from social_core.backends.open_id_connect import OpenIdConnectAuth
    import json
     
    class PixelPinOpenIDConnect(OpenIdConnectAuth):
        """PixelPin OpenID Connect authentication backend"""
        name = 'pixelpin-openidconnect'
        ID_KEY = 'sub'
        AUTHORIZATION_URL = 'https://login.pixelpin.io/connect/authorize'
        ACCESS_TOKEN_URL = 'https://login.pixelpin.io/connect/token'
        OIDC_ENDPOINT = 'https://login.pixelpin.io/'
        JWKS_URI = 'https://login.pixelpin.io/.well-known/jwks'
        ACCESS_TOKEN_METHOD = 'POST'
        REQUIRES_EMAIL_VALIDATION = False
    
        def get_user_details(self, response):
            """Return user details from PixelPin account"""
    
            first_name = response.get('given_name')
            last_name = response.get('family_name')
            sub = response.get('sub')
    
            username = first_name + last_name + sub
    
            return {'username': username,
                    'email': response.get('email'),
                    'full_name': first_name + ' ' + last_name,
                    'first_name': first_name,
                    'last_name': last_name}
    
        def user_data(self, access_token, *args, **kwargs):
            return self.get_json('https://login.pixelpin.io/connect/userinfo', headers={
                'Authorization': 'Bearer {0}'.format(access_token)
            })
    
  10. Next go to /mysite/urls.py and add the following code:

    url(r'^open_id_connect/', include('social_django.urls', namespace='social')),
    

    as show below:

  11. Next go to /mysite/core/views.py

  12. Add the following code:

    from social_django.models import UserSocialAuth
    

    near the top of the file as shown below:

  13. Add the following code under the def profile(request) function:

    try:
        pixelpin_login = user.social_auth.get(provider='pixelpin-openidconnect')
    except UserSocialAuth.DoesNotExist:
        pixelpin_login = None
    
    can_disconnect = (user.social_auth.count() > 1 or user.has_usable_password())
    

    and insert the following code into the profile function return request method, as shown below:

    'pixelpin_login': pixelpin_login,
    'can_disconnect': can_disconnect
    

Adding the SSO buttons

  1. Go to mysite/templates/registration/login.html and insert the following code to add the PixelPin Log In Button:

    <a href="{% url 'social:begin' 'pixelpin-openidconnect' %}">Log In Using PixelPin</a>
    
  2. Go to mysite/templates/registration/signup.html and insert the following code to add the PixelPin Register Button:

    <a href="{% url 'social:begin' 'pixelpin-openidconnect' %}">Register Using PixelPin</a>
    
  3. Add the official PixelPin SSO styling following this link.

  4. Go to mysite/core/templates/core/profile.html and insert the following code under Your User Data heading:

    <!-- This checks if the user is logged in using PixelPin -->
    {% if pixelpin_login %}
    <!-- Retrieving the user data from the sqlalchemy database -->
    <p>Username: {{ pixelpin_login.user.username }}</p>
    <p>Email: {{ pixelpin_login.user.email }}</p>
    <p>Full Name: {{ pixelpin_login.user.full_name}}</p>
    
    <!-- Checks if the user can disconnect from PixelPin depending on whether they have set a password or not -->
    {% if can_disconnect %}
    	<!-- Allows the user to disconnect their account from PixelPin -->
    	<form method="post" action="{% url 'social:disconnect' 'pixelpin-openidconnect' %}">
    		{% csrf_token %}
    		<button type="submit">Disconnect from PixelPin</button>
    	</form>
    {% else %}
    	<button type="button">Disconnect from PixelPin</button>
    	<p style="color: red">You must <a href="{% url 'password' %}">define a password</a> for your account before disconnecting from PixelPin.</p>
    {% endif %}
    <!-- Allows the user to connect their account to PixelPin -->
    {% else %}
    <a href="{% url 'social:begin' 'pixelpin-openidconnect' %}">Connect to PixelPin</a>
    {% endif %}
    

Testing the module

The Python Django example website login page should look something like this:

Test the plugin by pressing Log in Using PixelPin.

Contributing

Python Social Auth is an open-source project that allows developers using PixelPin to improve the plugin. The GitHub Repo can be found here.