LoginSignup
2
3

More than 3 years have passed since last update.

Flaskを使用したTwitterログイン連携用API作成 メモ

Posted at

作成する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_verifieroauth_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

参考情報

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3