[PYTHON] I'm having trouble with Django's Twitter authentication

2020-02-02 Update
I added the next parameter to the link destination of the "Login with Twitter" button.

Preface

Use social-auth-app-django

I'm building a web app in Django and decided to use Twitter authentication to log in. I heard that it's easy to use social-auth-app-django, so I decided to use it.

There is an official documentation on how to use social-auth-app-django called Python Social Auth ’s documentation. There are several other easy ways to get started by searching the net (such as this).

What this article deals with

Although social-auth-app-django is very easy to install, I still had some troubles in introducing it, so in this article I will write about the parts I was troubled with.

Before that, check the whole procedure

I think it's difficult to understand the part that I was suddenly troubled with, so I will briefly check the introduction procedure. I will not explain in detail. If you know it, please skip it.

1. Create an app for API access on Twitter

It is assumed that you are registered as a developer on Twitter. To create an app, simply press "Create an app" from the Dashboard (https://developer.twitter.com/en/apps) and fill in the required information.

In my case, I had a problem that I couldn't make a Twitter app. Also, Callback URLs are not required, but they must be set correctly to use the app for authentication. Details will be explained in [** "Worried place" **](#Worried place) at the bottom.

Assuming that you have a Twitter app and Callback URLs are set correctly, proceed to the next step.

2. Module installation

You can install it from PyPI with pip or pipenv.

$ pip install social-auth-app-django

3. API key and API secret key

You will need your API key and API secret key to access the Twitter API. To check, go to the details of your app from the Dashboard (https://developer.twitter.com/en/apps) and select the tab called Keys and tokens. Copy and use the two keys in the displayed Consumer API keys.

You shouldn't expose these keys, but you can write them directly in settings.py for development.

settings.py


SOCIAL_AUTH_TWITTER_KEY = 'XXXXXXXXXXXXXXX'
SOCIAL_AUTH_TWITTER_SECRET = 'YYYYYYYYYYYYYY'

If the project is published, it should not be included in the repository so that it can be read locally and elsewhere. You should be doing the same with the SECRET_KEY variable, so that should be fine.

4. Edit settings.py

Add'social_django' to ʻINSTALLED_APPS`.

settings.py


INSTALLED_APPS = [
    ...
    'social_django',    #add to
]

Add context_processors to TEMPLATES.

settings.py


TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                'social_django.context_processors.backends',        #add to
                'social_django.context_processors.login_redirect',  #add to
            ],
        },
    },
]

Add Name space and Backends.

settings.py


# For social-auth-app-django
SOCIAL_AUTH_URL_NAMESPACE = 'social'                #add to
AUTHENTICATION_BACKENDS = [
    'social_core.backends.twitter.TwitterOAuth',    #add to
    'django.contrib.auth.backends.ModelBackend',    #add to
]

5. Edit urls.py

Include'social_django.urls' in ʻurlspatterns`.

urls.py


urlpatterns = [
    ...
    path('', include('social_django.urls')),        #add to
    path('admin/', admin.site.urls),
    ...
]

This will allow you to respond to requests / login / twitter /, / complete / twitter /, / disconnect / twitter /.

By the way, the document has the following (old) writing style.

    url('', include('social_django.urls', namespace='social')),
  1. migrate

Once you've done this, migrate and update your DB. A table is added that associates your Twitter account with your Django account.

$ python manage.py makemigrations social_django
$ python manage.py migrate

7. Make a login page

When I looked at the article that introduced how to use social-auth-app-jango on the net, there was a page that made the login page from scratch and a page that explained only how to write the login button.

I was a little worried about what to do, so I will explain it below.

By the way, how to write a button is like this.

<button type="button" class="button"
    onclick="location.href='{% url 'social:begin' 'twitter' %}?next={{ next }}'">
Login with Twitter
</button>

If you install this, you will be able to authenticate with Twitter.

Where I was worried

I'll explain what I was having trouble with in the above steps.

I can't make a Twitter app

Perhaps those who have recently registered as a Twitter developer may not have this issue. I've been a developer for a long time, and when I tried to make an app for Django, I was told to apply again.

When I applied as instructed, the following page was displayed.

I thought that I should be able to make an application with this, but when I filled in the necessary items and read the notes, I thought that this was the end, and this screen was displayed.

Cause

I was able to solve it by referring to this page.

In conclusion, in my case, once I set a phone number for my Twitter account, I was able to create an app. I didn't know where to set the phone number at first, so I wrote it down. Instead of the developer's dashboard, I could normally set it from Twitter's home in "Settings & Privacy"> "Account".

Callback URLs

When I installed the "Login with Twitter" button and checked the operation for the first time, I got a 403 error. The cause was the setting of Callback URLs on the Twitter app side.

It was written properly in the this page that I referred to in the introduction, but at first I was looking at other pages, so Callback URLs were incorrect. It depends on the settings, so it's a good idea to check the urls.py in your environment.

If you set it up with the steps above in this article, it seems correct to set the following URL:

--When running locally - http://127.0.0.1:8000/complete/twitter/ --When deploying to the web --Service root / complete / twitter /

What to do with the login page

On the first page I referred to, I created a login / logout page from scratch, and also created an app for it (the app in the Django project). I wondered if I needed to do that, but it wasn't. Simply paste the button you wrote in ** "7. Create a login page" ** above onto the existing login page.

Of course, if you want to create a special page to log in with Twitter authentication, you can do so. My project doesn't even have a sign-up feature, so I only logged in with Twitter and deleted (commented out) the original form from the login page template.

Template rewriting

Templates for login / logout pages are usually in the'templates / registration /'folder. Actually, it depends on the project, so find the template used in that project and edit it.

Like this, I replaced the original form with a single button.

login.html


    ...
    <div align="center">
        <button type="button" class="button"
        onclick="location.href='{% url 'social:begin' 'twitter' %}?next={{ next }}'">
Login with Twitter</button>
    </div>
    
    <!--
    <div align="center">
        <form method="post" action="{% url 'login' %}">
            {% csrf_token %}
            <table>
                {{ form.as_table }}
            </table>
            <div>&nbsp;</div>
            <input type="submit" class="button" value="Login"/>
            <input type="hidden" name="next" value="{{ next }}"/>
        </form>
    </div>
    -->
    ...

The displayed login page If you don't comment out the original form, you can coexist with the "Login with Twitter" button. The logout page does not need to be changed.

To log in as admin

In the above example, you cannot log in with a password, but if you want to log in as admin, you can access the'service root / admin /'to open the login page for admin.

However, since I usually use the same logout page, I think that even if I log out as admin and press the "Login again" link, I will go to "Login with Twitter". I'm leaving it as it is because the admin page should be hard to access.

Recommended Posts

I'm having trouble with Django's Twitter authentication
I'm having trouble with instance variables being inherited in Python
Are you having trouble with "pipenv.exceptions.ResolutionFailure"?
Hit the Twitter API after Oauth authentication with Django
I'm trying to create an authentication / authorization process with Django