Facebookの場合
アプリケーション登録
以下のページからアプリケーション登録を行います。
Facebookではアプリ管理機能もFacebookアプリとして実現されているようです。初回のみ上記画面がでますので「アプリへ移動」をクリックしてください。
認証後「新しいアプリケーションを作成」をクリックすると上記のダイアログが表示されます。アプリ名を入力して「続行」をクリックしてください。
表示されている文字列を入力して「続行」をクリックしてください。
アプリの登録に成功すると上記画面になります。Twitterの「Consumer Secret」と同じく「App Secret」は絶対に他人に知られないようにしてください。
矢印の2か所にアプリのドメインを設定してください。開発環境のドメインは「localhost」となるでしょう。
本番公開時には本番用のドメインを設定する必要があるため、開発用、ステージング用、本番用など、環境にあわせて複数のアプリを登録するのもよいでしょう。
上図で入力するのは「Facebookアカウントでログイン」時にユーザーに表示する情報です。
「Authenticated Referrals」とは、必要なパーミッションに対して「なぜそれが必要か」をユーザーに説明するための設定で、上図のように設定すると、下図のように確認できます。Facebookの場合、通常のパーミッションと拡張パーミッションとでは、扱いが分けられているようです。拡張パーミッションはユーザーに警戒されがちなので誠意を持った説明をしましょう。実際のパーミッション要求は実行時にコードから設定する必要があります。
利用できるパーミッションの一覧については「パーミッション一覧」を参照してください。
サンプルコード
FacebookのOAuthはバージョン2.0です。2.0は1.0に比べて手順がかなり簡単なので、ここではライブラリを用いずに実装してみます。
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にリダイレクトされ、アプリケーション登録時に設定した内容でダイアログが表示されます。
許可(アプリへ移動)すると特殊なパラメータとともに以下のコードにリダイレクトされます。
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というライブラリでパースしています。









