[Twitter OAuth] pythonでtwitterアカウントのアクセストークン(access token)を取得する(OAuth認証)



# 実行環境

* PC: Mac
* Python Version: Python2.7
* Editor: PyCharm

# ライブラリのインストール

* OAuth認証のライブラリ

```
$ pip install oauth2
```

インストール後のoauth2情報を確認してみる

```
$ pip show oauth2
Name: oauth2
Version: 1.9.0.post1
Summary: library for OAuth version 1.9
Home-page: http://github.com/joestump/python-oauth2
Author: Joe Stump
Author-email: joe@simplegeo.com
License: MIT License
Location: /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages
Requires: httplib2
```

# Sample Code

```
# -*- coding:utf-8 -*-

import urllib
import oauth2 as oauth

request_token_url = 'https://twitter.com/oauth/request_token'
access_token_url = 'https://twitter.com/oauth/access_token'
authenticate_url = 'https://twitter.com/oauth/authorize'
callback_url = "https://www.aifan.jp?aaa=111,bbb=222,ccc=333333333333333/"
consumer_key = 'xxxxxxxxxxxxxxxxxxxxx'  # ご自身のアプリケーションのconsumer_keyに変更してください。
consumer_secret = 'xxxxxxxxxxxxxxxxxxxxx' # ご自身のアプリケーションのconsumer_keyに変更してください。

def get_request_token():
    consumer = oauth.Consumer(key=consumer_key, secret=consumer_secret)
    client = oauth.Client(consumer)

    # reqest_token を取得
    #resp, content = client.request(request_token_url, 'GET')
    resp, content = client.request('%s?&oauth_callback=%s' % \
                                   (request_token_url, callback_url))
    request_token = dict(parse_qsl(content))
    return request_token['oauth_token']


def parse_qsl(url):
    param = {}
    for i in url.split('&'):
        _p = i.split('=')
        param.update({_p[0]: _p[1]})
    return param


def get_access_token(oauth_token, oauth_verifier):
    consumer = oauth.Consumer(key=consumer_key, secret=consumer_secret)
    token = oauth.Token(oauth_token, oauth_verifier)

    client = oauth.Client(consumer, token)
    resp, content = client.request("https://api.twitter.com/oauth/access_token",
                                   "POST", body="oauth_verifier={0}".format(oauth_verifier))
    return content


if __name__ == '__main__':
    # request tokenを取得
    request_token = get_request_token()

    # request_tokenを認証endpointにつけて認証urlを生成する。
    # 認証urlの例:https://twitter.com/oauth/authorize?oauth_token=u2jGxAAAAAAAzgSuAAABX7Qdr6A
    authorize_url = '%s?oauth_token=%s' % (authenticate_url, request_token)

    # authorize_urlをクリックすると、Twitterの認証画面に遷移する。
    # 「連携アプリを認証」ボタンを押すと、事前に設定された callback_urlに飛ばされる。

    # callback_urlについている oauth_tokenとoauth_verifierでaccess tokenを取得
    # callback_url例：https://aifan.jp/?aaa=111,bbb=222,ccc=333333333333333/&oauth_token=kN1vfgAAAAAAzgSuAAABX7QOadg&oauth_verifier=oncUYcnbgt6SKSBGeVTrdhzmi7pU1xli
    oauth_token = "u2jGxAAAAAAAzgSuAAABX7Qdr6A"
    oauth_verifier = "fkbZAtEFHTUHpRBdshdEKe6oKGfozf3j"
    response = get_access_token(oauth_token, oauth_verifier)
    print(response)
    # response例：oauth_token=838678918160797696-wtAa3QTxDY3QrWCxSyvhARRK1H69MlK&oauth_token_secret=whtosInzvfGTYj4uDKJ3Q5BLWSjgROSvBmRI0eFLvPXTC&user_id=838678918160797696&screen_name=wen_htl&x_auth_expires=0
    # responseにあるoauth_tokenとoauth_token_secretがAPIをコールするときに必要なaccesss token とaccess secretです。
```

# 認証画面
生成された認証URLにアクセスすると、 下記のようなTwitter認証画面に飛ばされ、
**「連携アプリを認証」** ボタンを押すと、指定された `callback_url` に遷移する。

![Kobito.HVE1hM.png](https://qiita-image-store.s3.amazonaws.com/0/170309/a4e1083c-710b-b38d-8857-bf6f6e68e0ef.png "Kobito.HVE1hM.png")



# 注意点

TwitterのOAuthは、普通のOAuthフローとは違って、
[`GET oauth/authorize`](https://developer.twitter.com/en/docs/basics/authentication/api-reference/authorize) 認証画面に飛ばす前ではなく、 
リクエストトークンを取得する際に `CALLBACK URL` を指定することになる。

> Usage Note: An oauth_callback is never sent to `GET oauth/authorize` method, provide it to `POST oauth / request_token` instead.




# 参考
http://ikautimituaki.hatenablog.com/entry/20120516/1337142308
https://gist.github.com/laiso/826420/d12153d27d798e4a29727d27678cd9f4d7f62d08
https://github.com/joestump/python-oauth2/blob/master/oauth2/__init__.py
http://d.hatena.ne.jp/speg03/20091019/1255957580