paiza times

paizaがお届けする、テック・キャリア・マネジメント領域における「今必要な情報」を届けるWebメディア

logo

paizaがお届けする、テック・キャリア・マネジメント領域の「今必要な情報」を届けるWebメディア

2015年7月9日以降にFacebook認証でメールアドレスが取れない問題とその対策

f:id:paiza:20140712194904j:plainこんにちは、吉岡([twitter:@yoshiokatsuneo])です。

Facebook、LINE、TwitterなどのアカウントでログインするSNS連携認証は、簡単にログインできること、パスワード管理を一元化できることなどから多くのサービスで採用されています。

f:id:paiza:20150722161607p:plain

この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アドレスなど多くの情報が取得できていました。

f:id:paiza:20150722160346p:plain

API v2.4では、デフォルトでは"name", "id"のみ取得できるようになっています。

f:id:paiza:20150722160359p:plain

fieldsパラメータで"me?fields=email"のように指定することでE-Mailアドレスも取得できます。主要な公開情報の取得は、"me?fields=..."のように指定できます。

f:id:paiza:20150722160537p:plain

また、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のパラメータで以下のようにフィールドを指定します。

https://graph.facebook.com/me?fields=id,email,gender,link,locale,name,timezone,updated_time,verified,last_name,first_name,middle_name

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のスキルチェック

また、paiza転職をご利用いただいている企業の人事担当や、paiza転職を使って転職を成功した方々へのインタビューもございます。こちらもぜひチェックしてみてください。 詳しくはこちら

paizaのおすすめコンテンツ

PPG proken プログラミングゲーム「初恋 プログラミング研究会〜海に行こうよ〜」 PPG Bingo プログラミングゲーム「コードレビューBINGO!!」
paiza転職 paiza新卒 EN:TRY paizaラーニング 記事内に記載している情報は、記事公開時点でのものとなります。 Copyright Paiza, Inc, All rights reserved.