我正在尝试为Reddit's Api创建扩展名。 Reddit遵循OAuth 2获取access_token。我正在使用RestTemplate弹簧来发送所有对Reddit的POST请求。根据文档,我能够成功完成第一阶段。用户被重定向到Reddit,在那里他/她允许我的应用程序,Reddit然后通过代码将我重新导向到我的应用程序。但是,第二阶段似乎并不奏效。我必须使用代码来使另一个职位要求:Spring Social Reddit扩展 - OAuth 2 Access_token检索。 401错误
https://ssl.reddit.com/api/v1/access_token
这里是我获得AccessGrant(SpringSocial包装器的accessToken从reddit的发回)的尝试。 Spring Social需要你扩展OAuth2Template并从那里实现认证过程。在典型的Spring应用程序中,控制器将使用助手来调用RedditOAuth2Template.exchangeForAccess并将返回的AccessGrant保存到数据库中。
根据Reddit API文档401响应由于缺乏客户端凭证通过HTTP基本身份验证发生。但是,我在createHeaders(String username,String password)方法中这样做。
公共类RedditOAuth2Template扩展OAuth2Template {
private static final Logger LOG = LogManager.getLogger(RedditOAuth2Template.class);
private String client_id;
private String client_secret;
public RedditOAuth2Template(String clientId, String clientSecret) {
super(clientId, clientSecret, RedditPaths.OAUTH_AUTH_URL, RedditPaths.OAUTH_TOKEN_URL);
this.client_id = clientId;
this.client_secret = clientSecret;
setUseParametersForClientAuthentication(true);
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
protected AccessGrant postForAccessGrant(String accessTokenUrl, MultiValueMap<String, String> parameters) {
HttpHeaders headers = createHeaders(client_id, client_secret);
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set(accessTokenUrl, accessTokenUrl);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(parameters, headers);
ResponseEntity<Map> responseEntity = getRestTemplate().exchange(accessTokenUrl, HttpMethod.POST, requestEntity, Map.class);
Map<String, Object> responseMap = responseEntity.getBody();
return extractAccessGrant(responseMap);
}
/*
Reddit requires client_id and client_secret be
placed via HTTP basic Auth when retrieving the access_token
*/
private HttpHeaders createHeaders(String username, String password) {
String auth = username + ":" + password;
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(Charset.forName("US-ASCII")));
HttpHeaders headers = new HttpHeaders();
String authHeader = "Basic " + new String(encodedAuth);
headers.set("Authorization", authHeader);
return headers;
}
private AccessGrant extractAccessGrant(Map<String, Object> result) {
String accessToken = (String) result.get("access_token");
String scope = (String) result.get("scope");
String refreshToken = (String) result.get("refresh_token");
// result.get("expires_in") may be an Integer, so cast it to Number first.
Number expiresInNumber = (Number) result.get("expires_in");
Long expiresIn = (expiresInNumber == null) ? null : expiresInNumber.longValue();
return createAccessGrant(accessToken, scope, refreshToken, expiresIn, result);
}
}