SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Zusaar開発者に学ぶソーシャルアプリ入門

WebアプリにSNSアカウントでのログインを実装する

Zusaar開発者に学ぶソーシャルアプリ入門(1)

Facebookの場合

アプリケーション登録

 以下のページからアプリケーション登録を行います。

 Facebookではアプリ管理機能もFacebookアプリとして実現されているようです。初回のみ上記画面がでますので「アプリへ移動」をクリックしてください。

 認証後「新しいアプリケーションを作成」をクリックすると上記のダイアログが表示されます。アプリ名を入力して「続行」をクリックしてください。

 表示されている文字列を入力して「続行」をクリックしてください。

 アプリの登録に成功すると上記画面になります。Twitterの「Consumer Secret」と同じく「App Secret」は絶対に他人に知られないようにしてください。

 矢印の2か所にアプリのドメインを設定してください。開発環境のドメインは「localhost」となるでしょう。

 本番公開時には本番用のドメインを設定する必要があるため、開発用、ステージング用、本番用など、環境にあわせて複数のアプリを登録するのもよいでしょう。

 上図で入力するのは「Facebookアカウントでログイン」時にユーザーに表示する情報です。

 「Authenticated Referrals」とは、必要なパーミッションに対して「なぜそれが必要か」をユーザーに説明するための設定で、上図のように設定すると、下図のように確認できます。Facebookの場合、通常のパーミッションと拡張パーミッションとでは、扱いが分けられているようです。拡張パーミッションはユーザーに警戒されがちなので誠意を持った説明をしましょう。実際のパーミッション要求は実行時にコードから設定する必要があります。

 利用できるパーミッションの一覧については「パーミッション一覧」を参照してください。

通常のパーミッション
通常のパーミッション
拡張パーミッション
拡張パーミッション

サンプルコード

 FacebookのOAuthはバージョン2.0です。2.0は1.0に比べて手順がかなり簡単なので、ここではライブラリを用いずに実装してみます。

FacebookへリダイレクトするServlet(/source/src/sample/facebook/LoginServlet.java)
package sample.facebook;

import java.io.IOException;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        StringBuffer callbackURL = request.getRequestURL();
        int index = callbackURL.lastIndexOf("/");
        callbackURL.replace(index, callbackURL.length(), "").append("/callback");

        Properties prop = new Properties();
        prop.load(this.getClass().getClassLoader().getResourceAsStream("facebook.properties"));
        final String appId = prop.getProperty("appId");

        final String url =
            "https://www.facebook.com/dialog/oauth?client_id="
                + appId
                + "&redirect_uri="
                + callbackURL
                + "&scope=publish_stream";
        response.sendRedirect(url);
    }
}

 上記が「Facebookアカウントでログイン」で実行されるコードです。必要なパーミッションはscopeパラメータにカンマ区切りで列挙します。

 ユーザーはFacebookにリダイレクトされ、アプリケーション登録時に設定した内容でダイアログが表示されます。

 許可(アプリへ移動)すると特殊なパラメータとともに以下のコードにリダイレクトされます。

FacebookからリダイレクトされるServlet(/source/src/sample/facebook/CallbackServlet.java)
package sample.facebook;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONValue;

@SuppressWarnings("serial")
public class CallbackServlet extends HttpServlet {

    @SuppressWarnings("unchecked")
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        /*
         * アクセストークンの取得
         */
        final String callbackURL = request.getRequestURL().toString();
        final String code = request.getParameter("code");

        Properties prop = new Properties();
        prop.load(this.getClass().getClassLoader().getResourceAsStream("facebook.properties"));
        final String appId = prop.getProperty("appId");
        final String appSecret = prop.getProperty("appSecret");

        final String accessTokenURL =
            "https://graph.facebook.com/oauth/access_token?client_id="
                + appId
                + "&redirect_uri="
                + URLEncoder.encode(callbackURL, "UTF-8")
                + "&client_secret="
                + appSecret
                + "&code="
                + URLEncoder.encode(code, "UTF-8");
        final String accessTokenResult = httpRequest(new URL(accessTokenURL));

        // 結果のパース
        String accessToken = null;
        String[] pairs = accessTokenResult.split("&");
        for (String pair : pairs) {
            String[] kv = pair.split("=");
            if (kv.length != 2) {
                throw new RuntimeException("Unexpected auth response");
            } else {
                if (kv[0].equals("access_token")) {
                    accessToken = kv[1];
                }
            }
        }

        /*
         * APIの実行
         */
        final String apiURL =
            "https://graph.facebook.com/me?access_token=" + URLEncoder.encode(accessToken, "UTF-8");
        final String apiResult = httpRequest(new URL(apiURL));
        Map me = (Map) JSONValue.parse(apiResult);

        /*
         * ログイン処理
         */
        Map map = new HashMap();
        map.put("service", "Facebook");
        map.put("userId", String.valueOf(me.get("id")));
        map.put("name", String.valueOf(me.get("name")));
        map.put("accessToken", accessToken);
        request.getSession().setAttribute("loginUser", map);

        response.sendRedirect(request.getContextPath() + "/");
    }

    String httpRequest(URL url) throws IOException {
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("GET");
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line = null;
        String response = "";
        while ((line = reader.readLine()) != null) {
            response += line;
        }
        reader.close();
        conn.disconnect();
        return response;
    }
}

 ここでアクセストークンを取得します。OAuth2.0ではアクセストークンが1つの値にまとまりました。

 APIの実行にはこのアクセストークンを付与してHttpのリクエストを送信します。FacebookのAPIのレスポンスはJSONフォーマットです。ここではjson-simpleというライブラリでパースしています。

次のページ
mixiの場合

この記事は参考になりましたか?

この記事の著者

石井 賢司(イシイ ケンジ)

 会社員時代にGoogle App Engineに出会い傾倒、新規事業としてGAEを使った『決済できるソーシャルイベントプラットフォーム「Zusaar」』を立ち上げる。現在はフリーランスのエンジニアとして活動しつつ新たなサービスも模索中。Blog: http://d.hatena.ne.jp/knj77 ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/6572 2012/06/01 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー