はじめに
本日(2018/12/21)こんなメールが来ました。
え?使ってないよと思ったのですが「お前のプロジェクトで最近呼び出ししてるのこれな」と出ているのでどこで使っているのか確認&対処しました。
django-googleauth
このDjangoアプリ(Google+ API使ってるから直せと言われているプロジェクト)はユーザ管理にGoogle認証を使っているのですが、ライブラリは当時(2015年4月)に見つけてきたdjango-googleauthというものを使っています1。コードは非常にシンプル(必要最小限)なのですぐに読めます。
で、views.pyを見てみたところ、
GOOGLE_AUTH_ENDPOINT = 'https://accounts.google.com/o/oauth2/auth'
GOOGLE_TOKEN_ENDPOINT = 'https://accounts.google.com/o/oauth2/token'
GOOGLE_USERINFO_ENDPOINT = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect'
あー。
なおこのエンドポイントにアクセスして何しているかというと苗字と名前取っているだけです。
def callback(request):
省略
# get profile data
if GET_PROFILE:
headers = {'Authorization': 'Bearer %s' % attributes['access_token']}
resp = requests.get(GOOGLE_USERINFO_ENDPOINT, headers=headers)
if resp.status_code == 200:
profile = resp.json()
attributes['first_name'] = profile.get('given_name')
attributes['last_name'] = profile.get('family_name')
Google Sign-inでの方法
Googleから来ているメールによると「people.get使ってるのならGoogle Sign-inのやつを使うようにすればいい」と書いてあったのでGoogle Sign-inのページを確認。ページ末尾にOpenID Connectについての追加情報ページへのリンクがあったのでそっちに飛ぶ。
つまり、
- エンドポイントなどの情報が書かれたJSON(ディスカバリードキュメント)を取得。このURIはハードコードしていい。
- 取得したJSONからuserinfoのエンドポイントを取り出す。
- 取り出したエンドポイントに認証情報付きでアクセスして必要な情報を取得する。
とすればよいということになります。
で、そのように修正。まあディスカバリードキュメントが取れないことないやろとステータスチェック省いていますが良い子は真似してはいけません。
if GET_PROFILE:
# first, get user info endpoint
resp = requests.get('https://accounts.google.com/.well-known/openid-configuration')
userinfo_endpoint = resp.json().get('userinfo_endpoint')
headers = {'Authorization': 'Bearer %s' % attributes['access_token']}
#resp = requests.get(GOOGLE_USERINFO_ENDPOINT, headers=headers)
resp = requests.get(userinfo_endpoint, headers=headers)
if resp.status_code == 200:
profile = resp.json()
attributes['first_name'] = profile.get('given_name')
attributes['last_name'] = profile.get('family_name')
Google+ APIを無効化し、ちゃんと苗字と名前が取れることを確認。
あとがき
というわけで知らずに使っていたGoogle+ APIへの対応内容を書きました。
django-googleauthにプルリク投げようかなと思ったのですがもうメンテされてないっぽいので投げてません。
で、これがやや大事な話ですが、最近だとGoogle含めたsocial-auth-app-djangoがよく使われているみたいですね。2018/12/21時点だとこちらもGoogle+のエンドポイントがハードコーディングされています。social-auth-app-djangoはガワで本体はsocial-auth-core(パッケージ名はsocial_core)なので注意。まあこちらは活発に開発されているようなのでそのうち対応されると思いますが。
余談
OAuthだとかOpenIDに関して詳細に、「ガチに」解説した本ってあるのですかね(紙媒体がいい人)。ここら辺の技術を興亡含めてがっつり学びたいと思っているのですが。
-
一番初めはdjango-openid-authというライブラリを使っていたのですが、OpenID 2.0が廃止されたのでこれに変えたという経緯もあります。 ↩