2014-12-19

使用 Apache Oltu 作為需要 Basic Authorization 的 OAuth 2.0 Client - 以 Yahoo 為例

不管是直接用 Java HttpClient 或者 Apache Oltu 寫 OAuth 2.0 client 連 Google 或 facebook 一直沒什麼困難,直到遇到 Yaaaaaaahooooooo......挫賽!

拿 Authorization code 沒問題。
AuthenticationRequestBuilder builder = OAuthClientRequest.authorizationLocation("https://api.login.yahoo.com/oauth2/request_auth");
builder.setClientId(clientId);
builder.setResponseType(OAuth.OAUTH_CODE);
builder.setRedirectURI(redirectURI);
OAuthClientRequest request = builder.buildQueryMessage();
String oauth2URI = request.getLocationUri();

// ...用 brower 開啟 oauth2URI,輸入帳號密碼,然後同意資料外流,就會回到上面指定的 RedirectURI。

// read the code
OAuthAuthzResponse oar = OAuthAuthzResponse.oauthCodeAuthzResponse(request);
String oauth2Code = oar.getCode();

但是要拿 Code 換 Access token 就爛了,回應很簡單,一句「invalid_request」就想打發掉。

再回去仔細看看文件,果然事出必有因。


要加兩個 header,Content-Type 是制式的,沒問題。

但是 Authroization 是什麼鬼啊?先是 Basic,然後換行一堆亂碼!

後面的備註解釋得很簡單,搞半天,才知道是 "Basic " + Base64(clientId + ":" + clientSecret)。
// find the token
TokenRequestBuilder builder = OAuthClientRequest.tokenLocation("https://api.login.yahoo.com/oauth2/get_token");
builder.setGrantType(GrantType.AUTHORIZATION_CODE);
builder.setRedirectURI(redirectURI);
builder.setCode(oauth2Code);

URLConnectionClient httpClient = new URLConnectionClient();
OAuthClient oAuthClient = new OAuthClient(httpClient);

OAuthClientRequest request = builder.buildBodyMessage();
// yahoo 的重頭戲
request.addHeader(OAuth.HeaderType.CONTENT_TYPE, OAuth.ContentType.URL_ENCODED);
// yahoo The Authorization: Basic authorization header is generated through a Base64 encoding of client_id:client_secret per RFC 2617.
request.addHeader(OAuth.HeaderType.AUTHORIZATION, "Basic " + new String(Base64.encodeBase64(clientId + ":" + clientSecret).getBytes()));
OAuthAccessTokenResponse  oAuthResponse = oAuthClient.accessToken(request, requestMethod);
String accessToken = oAuthResponse.getAccessToken();

// read the user info
// yahoo 獨門用法
String xoauth_yahoo_guid = oAuthResponse.getParam("xoauth_yahoo_guid");
String resourceUrl = "https://social.yahooapis.com/v1/user/" + xoauth_yahoo_guid  + "/profile?format=json";
OAuthClientRequest bearerClientRequest = new OAuthBearerClientRequest(resourceUrl).buildQueryMessage();
// 另外一個用 header 取代網址參數的地方
bearerClientRequest.addHeader(OAuth.HeaderType.AUTHORIZATION, "Bearer " + accessToken);

OAuthResourceResponse resourceResponse = oAuthClient.resource(bearerClientRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
---
---
---

沒有留言:

張貼留言