- Flask を使用してTwitterログイン連携するためのAPI作成方法に関する個人用メモ。
- Google連携用APIを試した時と同様に、Docker起動できる形で過去に作成したTwitterログイン検証コードを部分的にAPI化した。
作成するAPI
認可リクエスト作成API
-
Twitter認可エンドポイントへアクセスするためのURLをパラメータをつけて生成・返却する。
-
oauth_token(request_token)
を取得し、認可リクエストURLにクエリパラメータとして設定する。 -
api_key
など固定の属性値は環境変数から取得する。 -
リクエスト例
POST /api/twitter/auth_request/create HTTP/1.1 Host: localhost:5000
-
レスポンス例
{ "authorization_request_url": "https://api.twitter.com/oauth/authenticate?oauth_token=1234ABCD" }
-
トークンリクエスト+ユーザー情報取得API
-
Twitterからの認可レスポンスとして受け取った
oauth_verifier
とoauth_token
を指定して、トークンリクエスト+ユーザー情報取得を行う。-
リクエスト例
POST /api/twitter/auth_request/complete HTTP/1.1 Host: localhost:5000 Content-Type: application/json Content-Length: 111 { "oauth_verifier":"AAABBBCCC", "oauth_token":"1234ABCD" }
-
レスポンス例
[ { "contributors_enabled": ..., "created_at": ..., "default_profile": ..., "default_profile_image": ..., "description": ..., "entities": { ... } }, ... } ]
-
プロジェクト構成
facebook_oidc
└─ docker-compose.yml
└─ twitter.env
│
└─ be
└─ Dockerfile
└─ requirements.txt
│
└─app
└─ app.py
│
└─ api
└─ __init__.py
│
└─views
└─ twitter.py
実装
-
docker-compose.yml
※起動時に環境変数ファイル
twitter.env
を読み込む。version: "3" services: be: container_name: be build: ./be env_file: twitter.env volumes: - ./be/app:/app ports: - "5000:5000" command: flask run --host 0.0.0.0 --port 5000 tty: true
-
twitter.env
- 環境変数ファイル。アプリケーション登録時に発行・設定した値を指定する。
TWITTER_API_KEY=YOUR_API_KEY TWITTER_API_SECRET=YOUR_API_SECRET TWITTER_AUTHORIZATION_ENDPOINT=https://api.twitter.com/oauth/authenticate TWITTER_REQUEST_TOKEN_ENDPOINT=https://api.twitter.com/oauth/request_token TWITTER_TOKEN_ENDPOINT=https://api.twitter.com/oauth/access_token TWITTER_USERINFO_ENDPOINT=https://api.twitter.com/1.1/users/lookup.json
-
be/requirements.txt
- Pythonライブラリ一式
Flask Flask-Cors requests_oauthlib
-
be/Dockerfile
FROM python:3.8 RUN mkdir /app ADD requirements.txt /app ENV PYTHONUNBUFFERED 1 EXPOSE 5000 WORKDIR /app RUN pip3 install -r requirements.txt
-
be/app/app.py
from api import app if __name__ == '__main__': app.run()
-
be/api/__init__.py
from flask import Flask from .views.twitter import twitter_router from flask_cors import CORS def create_app(): app = Flask(__name__) CORS(app, supports_credentials=True) app.register_blueprint(twitter, url_prefix='/api') return app app = create_app()
-
be/api/views/twitter.py
-
コントローラー
-
※エラーハンドリング皆無
import hashlib from flask import Flask, Blueprint, request, jsonify from requests_oauthlib import OAuth1Session import urllib.parse as parse import urllib.request as req import urllib.error as error import json import os from pprint import pprint # Routing Settings twitter_router = Blueprint('twitter_router', __name__) # Client Param api_key = os.getenv('TWITTER_API_KEY') api_secret = os.getenv('TWITTER_API_SECRET') # Twitter Endpoint authorization_endpoint = os.getenv('TWITTER_AUTHORIZATION_ENDPOINT') request_token_endpoint = os.getenv('TWITTER_REQUEST_TOKEN_ENDPOINT') token_endpoint = os.getenv('TWITTER_TOKEN_ENDPOINT') userinfo_endpoint = os.getenv('TWITTER_USERINFO_ENDPOINT') app = Flask(__name__) # Create Authorization Request Endpoint @twitter_router.route("/twitter/auth_request/create", methods=['POST']) def create(): # Obtaining a request token twitter = OAuth1Session(api_key, api_secret) oauth_callback = request.args.get('oauth_callback') res = twitter.post(request_token_endpoint, params={ 'oauth_callback': oauth_callback}) request_token = dict(parse.parse_qsl(res.content.decode("utf-8"))) oauth_token = request_token['oauth_token'] # Create Authz Request URL auth_request_url = authorization_endpoint+'?{}'.format(parse.urlencode({ 'oauth_token': oauth_token })) res_body = { "authorization_request_url": auth_request_url } return json.loads(json.dumps(res_body)) # Token Request And Get User Info Endpoint @twitter_router.route("/twitter/auth_request/complete", methods=['POST']) def complete(): # Parse Req Body jsonData = json.dumps(request.json) req_body = json.loads(jsonData) oauth_verifier = req_body['oauth_verifier'] oauth_token = req_body['oauth_token'] # Token Request twitter = OAuth1Session( api_key, api_secret, oauth_token ) res = twitter.post( token_endpoint, params={'oauth_verifier': oauth_verifier} ) access_token = dict(parse.parse_qsl(res.content.decode("utf-8"))) # Get User Info # https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup params = { 'user_id': access_token['user_id'] } twitter = OAuth1Session( api_key, api_secret, access_token['oauth_token'], access_token['oauth_token_secret'], ) response = twitter.get(userinfo_endpoint, params=params) results = json.loads(response.text) return jsonify(results)
-
起動
docker-compose up -d