[English]
2013-05-08 10:42 墳墓 (Brian Hsu) 前言
因為想要把自己四散各網站的相簿整合在一個單一的平台,所以在研究怎麼樣用 Java / Scala 操作 ImgUr API 第三版。
雖然說在 Java 的環境下已經有好用的 Scribe 來幫我們處理 OAuth 的部份,不過不幸的是原本附在 Scribe 裡面的 ImgUr API 已經過時了,不能直接使用。
幸好由於 Scribe 在設計上相當彈性,所以稍微看了一下 ImgUr 網站上的 API Version 3 的規格,也就把相關的東西實作出來了。
程式碼
新增的程式碼可以在 我在 GitHub 上的 Pull Reqeust 上看到,主要是新增兩個類別而已。
不過因為程式非常的短,而且加上 Scribe 本身的設計,他們是可以直接放在你的 Project 裡面的,所以如果現在就有需要,那只要把這兩個類別 Copy & Paste 到自己的專案中就可以了,並且參照使用範例就可以囉。
package org.scribe.builder.api;
import org.scribe.model.OAuthConfig;
import org.scribe.oauth.OAuthService;
import org.scribe.oauth.OAuthImgUr3Impl;
import org.scribe.model.Verb;
import org.scribe.extractors.JsonTokenExtractor;
import org.scribe.extractors.AccessTokenExtractor;
/**
* ImgUr API ver3 (OAuth 2)
*
* @author Brian Hsu
*
* @see <a href="http://api.imgur.com/">ImgUr API</a>
*/
public class ImgUr3Api extends DefaultApi20 {
private static final String authorizeURL = "https://api.imgur.com/oauth2/authorize";
private boolean isOOB(OAuthConfig config) {
return "oob".equals(config.getCallback());
}
@Override
public Verb getAccessTokenVerb() {
return Verb.POST;
}
@Override
public AccessTokenExtractor getAccessTokenExtractor() {
return new JsonTokenExtractor();
}
@Override
public String getAccessTokenEndpoint() {
return "https://api.imgur.com/oauth2/token";
}
@Override
public String getAuthorizationUrl(OAuthConfig config) {
String apiKey = config.getApiKey();
if (isOOB(config)) {
return String.format("%s?client_id=%s&response_type=pin", authorizeURL, apiKey);
} else {
return String.format("%s?client_id=%s&response_type=code", authorizeURL, apiKey);
}
}
@Override
public OAuthService createService(OAuthConfig config) {
return new OAuthImgUr3Impl(this, config);
}
}
package org.scribe.oauth;
import org.scribe.builder.api.DefaultApi20;
import org.scribe.model.OAuthConfig;
import org.scribe.model.OAuthConstants;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
public class OAuthImgUr3Impl extends OAuth20ServiceImpl {
private DefaultApi20 api;
private OAuthConfig config;
public OAuthImgUr3Impl(DefaultApi20 api, OAuthConfig config) {
super(api, config);
this.api = api;
this.config = config;
}
private boolean isOOB(OAuthConfig config) {
return "oob".equals(config.getCallback());
}
@Override
public Token getAccessToken(Token requestToken, Verifier verifier) {
OAuthRequest request = new OAuthRequest(
api.getAccessTokenVerb(),
api.getAccessTokenEndpoint()
);
String grantType = isOOB(config) ? "pin" : "authorization_code";
// ImgUr API ver 3 using POST to get token, and we need pass
// parameters using Body parameter, query string will not work.
request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
request.addBodyParameter("grant_type", grantType);
request.addBodyParameter("pin", verifier.getValue());
Response response = request.send();
return api.getAccessTokenExtractor().extract(response.getBody());
}
@Override
public void signRequest(Token accessToken, OAuthRequest request) {
if (accessToken != null) {
request.addHeader("Authorization", "Bearer " + accessToken.getToken());
} else {
request.addHeader("Authorization", "Client-ID " + config.getApiKey());
}
}
}
回響