LoginSignup
8
2

More than 5 years have passed since last update.

Google+ API使ってるところ直せと言われたので対応した話

Posted at

はじめに

本日(2018/12/21)こんなメールが来ました。

Google+_APIs_being_shutdown.png

え?使ってないよと思ったのですが「お前のプロジェクトで最近呼び出ししてるのこれな」と出ているのでどこで使っているのか確認&対処しました。

django-googleauth

このDjangoアプリ(Google+ API使ってるから直せと言われているプロジェクト)はユーザ管理にGoogle認証を使っているのですが、ライブラリは当時(2015年4月)に見つけてきたdjango-googleauthというものを使っています1。コードは非常にシンプル(必要最小限)なのですぐに読めます。

で、views.pyを見てみたところ、

googleauth/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'

あー。

なおこのエンドポイントにアクセスして何しているかというと苗字と名前取っているだけです。

googleauth/views.py抜粋
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についての追加情報ページへのリンクがあったのでそっちに飛ぶ。

つまり、

  1. エンドポイントなどの情報が書かれたJSON(ディスカバリードキュメント)を取得。このURIはハードコードしていい。
  2. 取得したJSONからuserinfoのエンドポイントを取り出す。
  3. 取り出したエンドポイントに認証情報付きでアクセスして必要な情報を取得する。

とすればよいということになります。
で、そのように修正。まあディスカバリードキュメントが取れないことないやろとステータスチェック省いていますが良い子は真似してはいけません。

googleauth/views.py修正版
    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に関して詳細に、「ガチに」解説した本ってあるのですかね(紙媒体がいい人)。ここら辺の技術を興亡含めてがっつり学びたいと思っているのですが。


  1. 一番初めはdjango-openid-authというライブラリを使っていたのですが、OpenID 2.0が廃止されたのでこれに変えたという経緯もあります。 

8
2
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
8
2