- 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