utamaro’s blog

誰かの役に立つ情報を発信するブログ

59.DjangoのでTwythonを使ったOAuthのサンプルを読んでみた。

参考にしたプロジェクトは↓です。

https://github.com/ryanmcgrath/twython-django

Twythonを使ってTwitterAPIを利用することができるようです。

An example Django application to showcase how to use OAuth with Twitter in Django using Twython.

と書かれていたので、OAuthの実装がわかるかな?と思って読んでみようと思いました。

それから、自分で実装できるようになると応用が効くと考えたからです。googleの認証にも使えそうですし。

requirements.txtがリポジトリ内に見当たらなかったので不満です。

なんで用意されていないのでしょうか。

setup.pyを見てみると↓のように書かれていました。

install_requires=['twython>=3.1.0', 'django'],

小さなプロジェクトというこのがわかります。

ちなみに、twythonのリンクは↓です。

https://twython.readthedocs.io/en/latest/usage/install.html

views.py

クラスベースの書き方ではないのですが、どうなのでしょうか。

良いか悪いかわかりませんが、こういうやり方もあるっていうのはドキュメントを読んで理解しているので良しとします。

https://github.com/ryanmcgrath/twython-django/blob/master/twython_django_oauth/views.py

OAuthの開始時に必要なcallbackや、認証後のurlを設定している箇所です。

    # Request an authorization url to send the user to...
    callback_url = request.build_absolute_uri(reverse('twython_django_oauth.views.thanks'))
    auth_props = twitter.get_authentication_tokens(callback_url)

    # Then send them over there, durh.
    request.session['request_token'] = auth_props

    request.session['next_url'] = request.GET.get('next',None)
    
    return HttpResponseRedirect(auth_props['auth_url'])

認証後にTwitterApiを使うところまで

コードを読んだ感じだと↓の順番で処理をすると良いみたいです。

  1. sessionからoauth_token, oauth_token_secretを取得する。
  2. twythonを使ってTwitterAPIを利用するための準備をする
  3. authorized_tokenをtwitterAPIを使って取得する
    oauth_token = request.session['request_token']['oauth_token']
    oauth_token_secret = request.session['request_token']['oauth_token_secret']
    twitter = Twython(settings.TWITTER_KEY, settings.TWITTER_SECRET,
                      oauth_token, oauth_token_secret)

    # Retrieve the tokens we want...
    authorized_tokens = twitter.get_authorized_tokens(request.GET['oauth_verifier'])
  1. authorized_tokenからscreen_nameを取得して、テーブル上にユーザーが登録されているか確認する
    1. 登録されている場合はuserオブジェクトを取得する
    2. 登録されていないなら、データを追加する
try:
    user = User.objects.get(username=authorized_tokens['screen_name'])
except User.DoesNotExist:
    # We mock a creation here; no email, password is just the token, etc.
    user = User.objects.create_user(authorized_tokens['screen_name'], "fjdsfn@jfndjfn.com", authorized_tokens['oauth_token_secret'])

DBに保存するのはoauth_token_secretで良いみたいです。

social-auth-app-djangoを使ったときは以下のデータがDB上に保存されます。

(一部マスキングしています)

{
    "auth_time": 1542545735,
    "id": 97379597xxxxxxxx620, 
    "access_token": {
        "oauth_token": "97379597xxxxxxxx620-Kn5iKEyyyyyyybzfc1QuFmyKt",
        "oauth_token_secret": "0TBySf6hjiSKqHnog4Qm6xZyyyyyyyyykmDaaos3CPxkLcn", 
        "user_id": "kdkdiem9597xxxxxxxx620", 
        "screen_name": "xxxxxxxxx"
    }
}

サンプルではoauth_tokenは保存していなかったので、どちらが正なのか判断できません。

Twythonのインスタンスを作成する際にoauth_tokenが必要かなと思うのですが、、、

ログイン時のsessionに含まれていると考えると必須ではないのかもしれません。

もしかすると、↓のコードでsaveとあるので、oauth_tokenが保存されているのかもしれません。(動かしていないのでわからないです)

profile = TwitterProfile()
profile.user = user
profile.oauth_token = authorized_tokens['oauth_token']
profile.oauth_secret = authorized_tokens['oauth_token_secret']
profile.save()

タイムラインを表示する

タイムラインを表示します。

def user_timeline(request):
    """An example view with Twython/OAuth hooks/calls to fetch data about the user in question."""
    user = request.user.twitterprofile
    twitter = Twython(settings.TWITTER_KEY, settings.TWITTER_SECRET,
                      user.oauth_token, user.oauth_secret)
    user_tweets = twitter.get_home_timeline()
    return render_to_response('tweets.html', {'tweets': user_tweets})

でもこれって、ログインしてない場合どうなるのでしょうか。

request.user.twitterprofileがNoneになるとエラーになるのですが、、、

ちなみに、htmlはこのようになっていました。

{% for tweet in tweets %}
    {{ tweet.text }}
{% endfor %}