-
-
Save shin1ogawa/04afa266f8f5b5ef81ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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