トップページから認証リンクを押すとサインインを求められ、ユーザーのアクセストークンをDBに保存して何らかの機能を提供するwebサービスを作る際のサンプル構成です。
(イメージとしては人事ったーみたいな感じの)
参考:Implementing Sign in with Twitter | Twitter Developers
使用パッケージ
Django
requests-oauthlib
URL構成
- /
- トップページ(/signin/へのリンクを貼る)
- /signin/
- ここにアクセスしたら認証ページにリダイレクト
- /callback/
- 認証から戻ってくるコールバックURL
- /app/
- アクセストークンを使用した機能を提供するページ
大まかな流れ
- ユーザーがトップページの認証リンクを踏む
- consumer keyとconsumer secretをAPIに送ってrequest token取得
- request tokenを含めた認証URLにユーザーをリダイレクト
- ユーザーが認証完了するとコールバックURLにリダイレクトされてくる
- コールバックURLに渡されたGETパラメータを元にアクセストークンを取得
- アクセストークンをDBに保存&セッションに保存して機能ページへリダイレクト
- 機能ページではセッションを持っていれば機能を提供、無ければサインインへリダイレクト
Model
とりあえず必要最低限
class User(models.Model):
id = models.BigIntegerField(primary_key=True)
access_token = models.CharField(max_length=255)
access_token_secret = models.CharField(max_length=255)
Djangoデフォルトのidを使わずユーザIDをプライマリキーにしてみました。
twitterのIDは32bitを超えているのでBigIntegerFieldを使います。
アクセストークンは認証解除→再認証などで変更されるのでプライマリキーにはできません。
View
# coding: utf-8
from django.shortcuts import render, redirect
from requests_oauthlib import OAuth1Session
from myapp.models import *
CONSUMER_KEY = "(コンシューマキー)"
CONSUMER_SECRET = "(コンシューマシークレット)"
# トップページ(認証へのリンクを設置するページ)
def index(request):
return render(request, 'myapp/index.html')
# 認証リンク
def signin(request):
# request token取得
callback_uri = "http://localhost:8000/callback/"
oauth = OAuth1Session(
CONSUMER_KEY,
client_secret=CONSUMER_SECRET,
callback_uri=callback_uri)
request_token_url = "https://api.twitter.com/oauth/request_token"
response = oauth.fetch_request_token(request_token_url)
# 認証用URL作成
redirect_url = "https://api.twitter.com/oauth/authenticate?oauth_token=" + response["oauth_token"]
# 認証へリダイレクト
return redirect(redirect_url)
# ユーザーが認証完了後にtwitterからリダイレクトされるURL
def callback(request):
request_token = request.GET["oauth_token"]; # リクエストトークンは以前と同じもの
verifier = request.GET["oauth_verifier"];
oauth = OAuth1Session(
CONSUMER_KEY,
client_secret=CONSUMER_SECRET,
resource_owner_key=request_token,
verifier=verifier)
access_token_url = "https://api.twitter.com/oauth/access_token"
# アクセストークン取得
response = oauth.fetch_request_token(access_token_url)
# DBに追加or更新
try:
# レコードが存在するか確認
user = User.objects.get(id=response["user_id"])
if user.access_token != response["oauth_token"]:
# アクセストークンが変わった場合更新
user.access_token = response["oauth_token"]
user.access_token_secret = response["oauth_token_secret"]
user.save()
except User.DoesNotExist:
# 存在しなかったら追加
user = User()
user.id = response["user_id"]
user.access_token = response["oauth_token"]
user.access_token_secret = response["oauth_token_secret"]
user.save()
# セッションにトークンを保存
request.session["access_token"] = response["oauth_token"]
# リダイレクト
return redirect("myapp.views.app")
# アクセストークンを使って機能を提供するページ
def app(request):
access_token = request.session.get("access_token", None)
if not access_token:
# セッションにアクセストークンが無ければサインインに移行
return redirect("myapp.views.signin")
user = User.objects.get(access_token=access_token)
# 以下、consumer key/secret、access token/secretの4つを使ってAPIを叩く
print "access_token_key: " + user.access_token
print "access_token_secret: " + user.access_token_secret
return render(request, 'myapp/app.html')
色々エラー処理とか足りてないかもしれないですがとりあえずこんなイメージです。
その他
公式のSign in with Twitterボタン画像はここからダウンロードできます。
Sign in with Twitter Resources | Twitter Developers
コメント