こんにちは、吉岡([twitter:@yoshiokatsuneo])です。
Facebook、LINE、TwitterなどのアカウントでログインするSNS連携認証は、簡単にログインできること、パスワード管理を一元化できることなどから多くのサービスで採用されています。
このSNS連携認証ですが、FacebookのSNS認証の仕様が2015年7月9日にリリースされたGraph API v2.4により、仕様が変更されています。
Introducing Graph API v2.4 https://developers.facebook.com/blog/post/2015/07/08/graph-api-v2.4/
特にSNS認証に関連した部分として、デフォルトで取得できるユーザ情報がidとnameのみになり、それ以外については明示的に指定しない限り取得できなくなっています。
APIのバージョンはFacebookアプリケーションごとに別になっており、作成された時期によってバージョンが異なるようです。そのため、以前は動いていたコードが、APIキーを変えたら動かなくなった、という問題が発生します。
ここでは、この問題の概要と対応策について説明します。
Facebook APIの変更点
実際のAPIの動作については、Graph API Exploreを使うと確認できます。
https://developers.facebook.com/tools/explorer/145634995501895/?method=GET&path=me
API v2.3の場合は、E-mailアドレスなど多くの情報が取得できていました。
API v2.4では、デフォルトでは"name", "id"のみ取得できるようになっています。
fieldsパラメータで"me?fields=email"のように指定することでE-Mailアドレスも取得できます。主要な公開情報の取得は、"me?fields=..."のように指定できます。
また、User APIの詳細についてはこちらで確認いただけます。
Graph API Reference - User https://developers.facebook.com/docs/graph-api/reference/user
APIのサポート期間
現時点で、v2.3時代に作ったAPIはすぐには無効にはなりませんが、古いAPIについては、新しいAPIがリリース後2年で終了します。2年が経過した時点で、v2.3ベースのAPIについても強制的にv2.4ベースのAPI呼び出しとして扱われます。
APIのサポート期間は以下で確認できます。
Platform Versioning https://developers.facebook.com/docs/apps/versions
対応方法
FacebookのSNS認証はJSONを用いたWeb APIとして実装されていますが、実際のアプリケーション開発では何らかのフレームワークを利用することが多いと思います。ここでは以下のような利用方法での対応を記載します。
- APIを直接呼び出す場合
- Facebook SDK(PHP, JavaScript, iOS, Android)
- Ruby on Rails(Omniauth)
- Node.js(Passport-facebook)
APIの直接利用
APIを直接利用する場合、URLのパラメータで以下のようにフィールドを指定します。
Facebook SDK(PHP, JavaScript, iOS, Android)での利用
Facebook SDKではAPIのエンドポイントでパラメータを指定します。
PHP
$request = new FacebookRequest( $session, 'GET', '/me?fields=id,email,gender,link,locale,name,timezone,updated_time,verified,last_name,first_name,middle_name' );
JavaScript
FB.api( "/me?fields=id,email,gender,link,locale,name,timezone,updated_time,verified,last_name,first_name,middle_name", function (response) {...} );
iOS
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"/me?fields=id,email,gender,link,locale,name,timezone,updated_time,verified,last_name,first_name,middle_name" parameters:params HTTPMethod:@"GET"]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { ... }];
Android
new GraphRequest( AccessToken.getCurrentAccessToken(), "/me?fields=id,email,gender,link,locale,name,timezone,updated_time,verified,last_name,first_name,middle_name", null, HttpMethod.GET, new GraphRequest.Callback() { public void onCompleted(GraphResponse response) { /* handle the result */ } } ).executeAsync();
Ruby on Rails(Omniauth)での利用
Omniauthでは、v2.1.0でデフォルトでname,emailフィールドが含まれるように対応予定となっています。Github上の最新コミットでは7月19日にmasterブランチに反映されています。それ以前のバージョンでは、以下のようにfieldsを指定します。
Devise.setup do |config| config.omniauth(:facebook, 'APIキー', 'SECRETキー', {:scope => 'email', :info_fields => 'id,email,gender,link,locale,name,timezone,updated_time,verified,last_name,first_name,middle_name'}) end
関連情報: Facebook OAuth2 Strategy for OmniAuth (Github) https://github.com/mkdynamic/omniauth-facebook
Fix default info_fields to 'name,email' #209 (Github) https://github.com/mkdynamic/omniauth-facebook/pull/209
Facebook OAuth is not returning email in user info (stackoverflow) http://stackoverflow.com/questions/31503090/facebook-oauth-is-not-returning-email-in-user-info/31554071#31554071
Node.js(Passport-facebook)での利用
Node.js用の認証ライブラリPassport-facebookを利用する場合、StrategyクラスのprofileFieldsで取得するフィールドを指定します。
passport.use(new FacebookStrategy({ clientID: config.facebook.clientID, clientSecret: config.facebook.clientSecret, callbackURL: config.facebook.callbackURL, profileFields: ['displayName', 'id', 'email', 'gender', 'link', 'locale', 'name', 'timezone', 'updated_time', 'verified'], },
なお、上記対策を行わなずにE-Mailアドレスを利用した場合、以下のようなエラーが発生します。
/app/server/auth/facebook/passport.js:21 ^ email: profile.emails[0].value, TypeError: Cannot read property '0' of undefined
関連情報: passport-facebook https://github.com/jaredhanson/passport-facebook
Passport-Facebook not providing email even if it is in scope (stackoverflow) http://stackoverflow.com/questions/31279066/passport-facebook-not-providing-email-even-if-it-is-in-scope/31554393#31554393
まとめ
Facebook Graph API v2.4のリリースに伴う、Facebook認証でメールアドレスが取得できなくなる問題と、その対応方法について説明しました。新規に作成したFacebookアプリケーションについては、API v2.4しか利用できません。また、v2.3以前のAPIを既に作成して利用している場合は2年間は利用できますが、直前・直後であわてないように、また新しいフレームワーク等は最新のAPIを前提とすることになると思いますので早めに対応されることをお勧めします。
paizaは、技術を追い続けることが仕事につながり、スキルのある人がきちんと評価される場を作ることで、日本のITエンジニアの地位向上を目指したいと考えています。
「paiza転職」は、自分のプログラミング力が他社で通用するか(こっそり)腕試しができる、IT/Webエンジニアのための転職サービスです。プログラミングスキルチェック(コーディングのテスト)を受けて、スコアが一定基準を超えれば、書類選考なしで複数の会社へ応募ができます。
まずはスキルチェックだけ、という使い方もできます。すぐには転職を考えていない方でも、自分のプログラミングスキルを客観的に知ることができますので、興味がある方はぜひ一度ご覧ください。
また、paiza転職をご利用いただいている企業の人事担当や、paiza転職を使って転職を成功した方々へのインタビューもございます。こちらもぜひチェックしてみてください。 詳しくはこちら