stMind

about Tech, Computer vision and Machine learning

Github APIでWorking with two factor authentication

Githubで二段階認証を設定している場合に、ベーシック認証はAuthentication Codeの入力が必要になります。
rubyで書かれたdefunkt/gist · GitHubを参考に、アクセストークンを取得するサンプルを書いて試してみました。

Other Authentication Methods | GitHub API

通常のベーシック認証のステップでサーバから401でヘッダにX-GitHub-OTP: required; :2fa-typeのレスポンスが返ってくるので、その場合はSMSで受け取った6桁の認証コードをX-GitHub-OTPヘッダに入れて送ります。
以上で、アクセストークンを含むメッセージを得ることが出来ます。

pythonだとrequestsを使うと簡単でした。pitはユーザ名とパスワードの手入力が手間だったたので使いました。

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


from pit import Pit
import requests
import getpass
import json

HTTPUnauthorized = 401
HTTPCreated = 201


def main():
    conf = Pit.get("api.github.com",
                   {"require":
                    {"username": "Your username",
                     "password": "Your password"}})

    # Start Process
    print "Obtaining OAuth2 access_token from github."
    username = conf["username"] or raw_input("Github username: ")
    password = conf["password"] or getpass.getpass("Github password: ")
    if username and password:
        print "username and password set"

    url = "https://api.github.com/authorizations"
    payload = {"scopes": ["repo"],
               "note": "Test Script for Obtaining Token"}
    headers = {"content-type": "application/json"}
    auth = (username, password)

    r = requests.post(url, data=json.dumps(payload),
                      headers=headers, auth=auth)

    if r.status_code == HTTPUnauthorized and r.headers["X-Github-OTP"]:
        twofa_code = raw_input("2-factor auth code: ")
        headers["X-Github-OTP"] = twofa_code
        rr = requests.post(url, data=json.dumps(payload),
                           headers=headers, auth=auth)

    if rr.status_code == HTTPCreated:
        print "Success!: %s" % rr.json()["token"]
    elif rr.status_code == HTTPUnauthorized:
        print "Error: %s" % rr.json()["message"]
    else:
        print "Got %s: " % rr.content


if __name__ == '__main__':
    main()