使用Python的Web应用程序框架”Django”尝试进行Twitter身份验证

总结

之前,我发布了一篇关于如何直接使用Python脚本调用Twitter API的文章。
我尝试着使用Python来玩弄Twitter API。

不过,如果是这样的话

    • Consumer Key

 

    Consumer Secret

除此之外、

    • Access Token

 

    Access Token Secret

由于需要特定的用户,所以只能在特定的用户下进行API操作。

因此,我們利用Python的Web應用程式框架「Django」,在瀏覽器上實現了Twitter認證並進行了每個帳號的認證處理。

Django是什么

我叫做“杰克”。

思想上,我们将按照model-view-template设计模式进行开发。
与model-view-controller相似,但似乎有所不同。

(谢谢 @udoooom 指正!)

另外,这个框架非常容易开发,并且能够在几个小时之内完成安装到Twitter认证成功的过程。

步骤

开发环境

    • Python == 3.5.1

 

    • Django == 2.0.1

 

    social-auth-app-django == 2.1.0

另外,TwitterAPI的Consumer信息是从使用Python玩转Twitter API中获取的,我们将直接使用这些信息,所以如果您还没有创建,请先参考这篇文章并创建Twitter应用。

安装模块

暂时先安装原始版本的Django框架。

pip install django

创建项目

首先我们要创建项目。

django-admin startproject project

项目创建之初的目录结构如下。

.
└── project
    ├── manage.py
    └── project
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

进行DB迁移

Django 包含了数据库功能, 默认情况下使用的是 sqlite3。

首先,让我们进行迁移。

cd myApp
python manage.py migrate

顺利完成。

screencapture- 2018-01-10 14.55.28.png

创建管理员用户

接下来,我们将创建一个管理用户。

python manage.py createsuperuser

请提供您的用户名/电子邮件地址/密码/确认密码。

screencapture- 2018-01-10 14.56.46.png

启动服务器

让我们在这种状态下试着启动服务器。

python manage.py runserver
screencapture- 2018-01-10 20.23.39.png

当在浏览器中访问http://localhost:8000时,应该会显示以下应用界面。

screencapture- 2018-01-10 15.10.17.png

登录管理界面

DJango会默认为我们准备好一个管理界面。

我将访问 http://localhost:8000/admin。

请您输入之前创建的用户名和密码。

screencapture- 2018-01-10 15.11.33.png

登录成功!!!

创建应用程序

下一步是创建应用程序。

据说在Django中可以在一个项目中创建多个应用程序。

python manage.py startapp twitterManager

然后,目录结构会变成这样。

.
└── project
    ├── db.sqlite3
    ├── manage.py
    ├── project  # 共通
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── twitterManager  # アプリ①
        ├── __init__.py
        ├── admin.py
        ├── apps.py
        ├── migrations
        │   └── __init__.py
        ├── models.py
        ├── tests.py
        └── views.py

为了将创建的应用程序纳入项目管理的范围,需要编辑以下文件。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
+   'twitterManager.apps.TwittermanagerConfig',
]

然后,您可以使用以下命令将其放入迁移目标。

python manage.py makemigrations twitterManager
python manage.py migrate twitterManager

※由于没有任何更改,因此不会产生差异,但为了谨慎起见。

安装用于Twitter认证的模块。

我們這次將使用social-auth-app-django。

pip install social-auth-app-django

创建认证信息

请创建以下文件,并填写Twitter应用程序的Consumer信息。

SOCIAL_AUTH_TWITTER_KEY = 'XXXXXXXXXXXXXXX'
SOCIAL_AUTH_TWITTER_SECRET = 'YYYYYYYYYYYYYY'

※对于git仓库,我们希望将认证信息保留在git的管理之外,因此应将其添加到.gitignore文件中。

**twitter.py

对settings.py的修改

我会将其改成类似的感觉。

"""
Django settings for project project.

Generated by 'django-admin startproject' using Django 2.0.1.

For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""

import os
+ from project.configs import twitter

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'twitterManager.apps.TwittermanagerConfig',
+   'social_django',
]

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',
]

ROOT_URLCONF = 'project.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
+               'social_django.context_processors.backends',
+               'social_django.context_processors.login_redirect',
            ],
        },
    },
]

WSGI_APPLICATION = 'project.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

STATIC_URL = '/static/'

+ AUTHENTICATION_BACKENDS = [
+       'social_core.backends.twitter.TwitterOAuth',
+       'django.contrib.auth.backends.ModelBackend',
+   ]

+ SOCIAL_AUTH_TWITTER_KEY = twitter.SOCIAL_AUTH_TWITTER_KEY
+ SOCIAL_AUTH_TWITTER_SECRET = twitter.SOCIAL_AUTH_TWITTER_SECRET

添加登录/登出界面

接下来,我们将准备显示登录界面和退出界面的操作。

我将创建以下文件。

from django.contrib import admin
from django.urls import path
from django.conf.urls import include
import django.contrib.auth.views

urlpatterns = [
    path('', include('social_django.urls', namespace = 'social')),
    path('login/',
            django.contrib.auth.views.login,
            {
                'template_name': 'login/index.html',
            },
            name='login'),
    path('logout/',
        django.contrib.auth.views.logout,
        {
            'template_name': 'logout/index.html',
        },
        name='logout'),

]

创建登录页面和登出页面各自的HTML。由于这只是一个快速确认显示水平的草稿,所以随意设计即可。

<html>
<head>
 <title>ログイン</title>
</head>
<body>
  <div>
    <button type="button" onclick="location.href='{% url 'social:begin' 'twitter' %}'">ログイン</button>
  </div>
</body>
</html>
<html>
<head>
 <title>ログアウト</title>
</head>
<body>
  <div>
    <p>
      ログアウトしました。
    </p>
    <p>
      <a href="/twitterManager/login"><button type="button" >ログインページへ</button></a>
    </p>
  </div>
</body>
</html>

最后,我们需要编辑现有的project/urls.py文件。

from django.contrib import admin
from django.urls import path
+ from django.conf.urls import include

urlpatterns = [
    path('admin/', admin.site.urls),
+   path('twitterManager/', include('twitterManager.urls')),
]

执行迁移

由于新增了social-auth-app-django,需要进行迁移。
如果在启动服务器之前不进行迁移,则会发生错误。

screencapture- 2018-01-10 17.42.31.png

发生了。

當需要遷移時,我們應該關注伺服器啟動時的日誌。

screencapture- 2018-01-10 21.11.30.png
python manage.py migrate
screencapture- 2018-01-10 20.27.22.png

确认

在这种状态下启动服务器。

python manage.py runserver

登录界面

screencapture- 2018-01-10 16.23.34.png

登出页面

screencapture- 2018-01-10 16.23.45.png

我想你会看到一个非常简洁的页面。笑

然而在这里出现了问题

当我兴高采烈地点击登录按钮时,

screencapture- 2018-01-10 21.09.31.png

发生了401错误。

原因是未填寫回調URL。

如果在创建Twitter应用程序时未输入回调URL,则在作为Web系统使用时可能会发生401错误。

由于它不是特别使用的项目,所以暂时先放一个假的URL吧。

screencapture- 2018-01-10 17.38.58.png

这样联络确认画面显示出来了!!!

screencapture- 2018-01-10 17.39.21.png

这一次才是机会!

一旦点击认证按钮,即可连接应用程序。

screencapture- 2018-01-10 17.44.50.png

哇哦…!! (wktk)

screencapture- 2018-01-10 21.17.44.png
image.png

在社交认证成功后进行重定向的原因。

需要指定在认证成功时将跳转到的重定向URL。
默认情况下,似乎会跳转到/accounts/profile/。

暂时快速准备一个会员首页界面,然后尝试进行重定向。

+ from . import views

urlpatterns = [
    path('', include('social_django.urls', namespace = 'social')),
+   path('top/', views.top_page, name="top_page"),
    path('login/',
            django.contrib.auth.views.login,
            {
                'template_name': 'login/index.html',
            },
            name='login'),
    path('logout/',
        django.contrib.auth.views.logout,
        {
            'template_name': 'logout/index.html',
        },
        name='logout'),

]
from django.shortcuts import render

# Create your views here.

from django.shortcuts import render
from django.http.response import HttpResponse
from django.contrib.auth.decorators import login_required
from social_django.models import UserSocialAuth

@login_required
def top_page(request):
    user = UserSocialAuth.objects.get(user_id=request.user.id)
    pageDic = {
        'hoge': 'fuga',
        'user': user
    }
    return render(request, 'top/index.html', pageDic)
<html>
<head>
 <title>会員トップ</title>
</head>
<body>
  <div>
    <h1>会員トップ</h1>
    <h2>{{ user }}</h2>
    <div>
      <p>UserId:{{ user.access_token.user_id }}</p>
      <p>OAuthTokenSecret:{{ user.access_token.oauth_token_secret }}</p>
      <p>OAuthToken:{{ user.access_token.oauth_token }}</p>
      <p>ScreenName:{{ user.access_token.screen_name }}</p>
    </div>
    <h3>hoge:{{ hoge }}</h3>
    <p>
      <a href="/twitterManager/logout"><button type="button" >ログアウト</button></a>
    </p>
  </div>
</body>
</html>
+ SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/twitterManager/top'

这样怎么样…!

screencapture- 2018-01-10 20.10.52.png

抓到了!!!

请在其他账号上确认

等等,你说的是不是…?
因为Twitter应用程序的所有者和Bakira_Tech的认证帐户是一样的,所以它只是正常运行而已,可能其他账户无法使用?我有点担心…

screencapture- 2018-01-10 20.14.24.png

对不起,我打扰你了!

这样一来,Twitter认证就完成了,接下来只需使用OAuthToken将逻辑和设计融入其中,似乎可以制作出相当不错的东西呢♪

最终构成的结果

成为了以下这样!(并不是最佳实践,所以请勿介意……orz)

.
└── project
    ├── db.sqlite3
    ├── manage.py
    ├── project
    │   ├── __init__.py
    │   ├── configs
    │   │   └── twitter.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── twitterManager
        ├── __init__.py
        ├── admin.py
        ├── apps.py
        ├── migrations
        │   └── __init__.py
        ├── models.py
        ├── templates
        │   ├── login
        │   │   └── index.html
        │   ├── logout
        │   │   └── index.html
        │   └── top
        │       └── index.html
        ├── tests.py
        ├── urls.py
        └── views.py

结束

因为这是一个从零开始的任务,所以我一边查阅资料一边摸索尝试,但即使如此,我还是能够在大约五个小时的学习成本内成功创建一个能够显示会员首页的程序。

Django框架真的很有趣!♪

我受益于参考的文章。

太感谢了!!!
– 使用Django进行Twitter OAuth
– 在Django中进行Oauth认证后调用Twitter API
– 创建了一个实现社交过滤功能的Twitter客户端
– 如果出现OAuth::Unauthorized 401 Unauthorized错误

广告
将在 10 秒后关闭
bannerAds