Skip to content

Instantly share code, notes, and snippets.

@shin1ogawa
Created April 9, 2012 16:08
Show Gist options
  • Save shin1ogawa/04afa266f8f5b5ef81ab to your computer and use it in GitHub Desktop.
Save shin1ogawa/04afa266f8f5b5ef81ab to your computer and use it in GitHub Desktop.
import java.io.*;
import java.net.*;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.*;
@SuppressWarnings("serial")
public class FacebookServlet extends HttpServlet {
static final Logger logger = Logger.getLogger(FacebookServlet.class.getName());
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String state = request.getParameter("state");
if ("getAuthCode".equals(state) == false) {
respondRedirectToGetAuthorizationCode(request, response);
}
String error = request.getParameter("error");
if ("access_denied".equals(error)) {
respondForShowDeniedByUser(request, response);
} else {
respondForAuthorizedByUser(request, response);
}
}
void respondForAuthorizedByUser(HttpServletRequest request,
HttpServletResponse response) throws IOException {
String code = request.getParameter("code");
String accessTokenResponse = retrieveAccessToken(code,
buildServerNameAndPort(request) + PATH);
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().println("retrieveAccessToken=" + accessTokenResponse);
String[] splittedResponses = accessTokenResponse.split("\\&");
String accessToken = null;
for (String splittedResponse : splittedResponses) {
if (splittedResponse.startsWith("access_token=")) {
accessToken = splittedResponse.split("=")[1];
break;
}
}
response.getWriter().println("accessToken=" + accessToken);
response.getWriter().println();
// 試しに取得したアクセストークンを使って、いくつかの情報にアクセスしてみる。
// アクセストークンの期限が切れていた場合は、それとわかる400が返ってくるので、再取得しなければならない。
// https://developers.facebook.com/docs/authentication/access-token-expiration/
PrintWriter writer = response.getWriter();
HttpURLConnection c;
BufferedReader reader;
String line;
// ユーザ自身の情報
c = (HttpURLConnection) new URL(
"https://graph.facebook.com/me?access_token=" + accessToken)
.openConnection();
reader = new BufferedReader(new InputStreamReader(c.getInputStream(), "utf-8"));
while ((line = reader.readLine()) != null) {
writer.println(line);
}
response.getWriter().println();
// 友達の一覧
c = (HttpURLConnection) new URL(
"https://graph.facebook.com/me/friends?limit=5&access_token="
+ accessToken).openConnection();
reader = new BufferedReader(new InputStreamReader(c.getInputStream(), "utf-8"));
while ((line = reader.readLine()) != null) {
writer.println(line);
}
response.getWriter().println();
response.flushBuffer();
}
void respondForShowDeniedByUser(HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().println(request.getQueryString());
response.flushBuffer();
}
void respondRedirectToGetAuthorizationCode(HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.sendRedirect(getUrlToGetAutherizationCode(buildServerNameAndPort(request)
+ PATH));
}
static CharSequence buildServerNameAndPort(HttpServletRequest request) {
StringBuilder b = new StringBuilder(request.getScheme()).append("://")
.append(request.getServerName());
if (request.getServerPort() != 80 && request.getServerPort() != 443) {
b.append(":").append(request.getServerPort());
}
return b;
}
static final String CLIENT_ID = System.getProperty("fb.client_id");
static final String CLIENT_SECRET = System.getProperty("fb.client_secret");
static final String PATH = "/fb";
/**
* @param callbackURI
* @return 認可コードを取得するためのURL
* @throws IOException
* @author shin1ogawa
* @see <a href="https://developers.facebook.com/docs/authentication/server-side/">Core Concepts › Authentication › Server-Side Authentication</a>
* @see <a href="https://developers.facebook.com/docs/authentication/permissions/">Core Concepts › Authentication › Permissions</a>
*/
static String getUrlToGetAutherizationCode(String callbackURI)
throws IOException {
// パラメータを組み立てる
StringBuilder b = new StringBuilder();
b.append("response_type=code");
b.append("&client_id=").append(URLEncoder.encode(CLIENT_ID, "utf-8"));
b.append("&redirect_uri=").append(URLEncoder.encode(callbackURI, "utf-8"));
b.append("&scope=").append(URLEncoder.encode("user_about_me,offline_access", "utf-8"));
b.append("&state=getAuthCode");
return "https://www.facebook.com/dialog/oauth?" + b.toString();
}
/**
* FBからコールバックされた際に渡される{@code authorizationCode}を使い、アクセストークンを取得し、返す。
*
* @param authorizationCode FBからコールバックされた際に渡される認可コード
* @param callbackURI
* @return アクセストークンが含まれた文字列
* @throws IOException
* @author shin1ogawa
* @see <a href="https://developers.facebook.com/docs/authentication/server-side/">Core Concepts › Authentication › Server-Side Authentication</a>
*/
static String retrieveAccessToken(String authorizationCode,
String callbackURI) throws IOException {
// パラメータを組み立てる
StringBuilder b = new StringBuilder();
b.append("code=").append(URLEncoder.encode(authorizationCode, "utf-8"));
b.append("&client_id=").append(URLEncoder.encode(CLIENT_ID, "utf-8"));
b.append("&client_secret=").append(URLEncoder.encode(CLIENT_SECRET, "utf-8"));
b.append("&redirect_uri=").append(URLEncoder.encode(callbackURI, "utf-8"));
b.append("&grant_type=authorization_code");
byte[] payload = b.toString().getBytes();
// POST メソッドでリクエストする
HttpURLConnection c = (HttpURLConnection) new URL(
"https://graph.facebook.com/oauth/access_token")
.openConnection();
c.setRequestMethod("POST");
c.setDoOutput(true);
c.setRequestProperty("Content-Length", String.valueOf(payload.length));
c.getOutputStream().write(payload);
c.getOutputStream().flush();
// トークン類が入ったレスポンスボディの内容を返す(JSONで返される)
StringBuilder respondedJSON = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
respondedJSON.append(line).append("\n");
}
return respondedJSON.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment