【发布时间】:2016-02-17 00:25:42
【问题描述】:
我从 Withings API 获取用户数据访问令牌时遇到问题(api 文档的第 3 步): http://oauth.withings.com/api/doc#api-OAuth_Authentication-access_token
服务返回“无效签名”错误。
这是我的方法:
private static String getSignature(String url, String params, String authSecret) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
StringBuilder base = new StringBuilder();
base.append("GET&");
base.append(url);
base.append("&");
base.append(params);
byte[] keyBytes;
if (authSecret != null) {
keyBytes = (secret + "&" + authSecret + "&").getBytes(ENC);
} else {
keyBytes = (secret + "&").getBytes(ENC);
}
SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA1);
Mac mac = Mac.getInstance(HMAC_SHA1);
mac.init(key);
Base64 base64 = new Base64();
return new String(base64.encode(mac.doFinal(base.toString().getBytes(ENC))), ENC).trim();
}
public static AuthResponse getAccessToken(AuthRequest request) {
try {
CloseableHttpClient httpclient = HttpClients.createDefault();
String url = "https://oauth.withings.com/account/access_token";
URIBuilder builder = new URIBuilder(url);
List<NameValuePair> valuePairs = new ArrayList<>();
valuePairs.add(new BasicNameValuePair("oauth_consumer_key", key));
valuePairs.add(new BasicNameValuePair("oauth_nonce", "" + (int) (Math.random() * 100000000)));
valuePairs.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
valuePairs.add(new BasicNameValuePair("oauth_timestamp", "" + (System.currentTimeMillis() / 1000)));
valuePairs.add(new BasicNameValuePair("oauth_token", request.getOauthToken()));
valuePairs.add(new BasicNameValuePair("oauth_version", "1.0"));
valuePairs.add(new BasicNameValuePair("userid", request.getUserId()));
String signature = getSignature(URLEncoder.encode(url, ENC), URLEncoder.encode(URLEncodedUtils.format(valuePairs, ENC), ENC), request.getOauthTokenSecret());
valuePairs.add(new BasicNameValuePair("oauth_signature", signature));
builder.addParameters(valuePairs);
URI uri = builder.build();
HttpGet httpget = new HttpGet(uri);
HttpResponse response = httpclient.execute(httpget);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder sb = new StringBuilder();
String result;
while ((result = reader.readLine()) != null) {
sb.append(result);
}
return null;
} catch (Exception e) {
throw new RuntimeException("*Error during getAccessToken request");
}
}
我也尝试不使用“authSecret”参数来生成签名(就像在 withings 规范中一样),尝试更改顺序并按字母顺序放置“oauth_signature”参数,但我没有成功 谁能帮我? PS:在Api文档的前两个步骤中,我使用这个签名生成器成功获得了oauth_token、oauth_token_secret、userid。
【问题讨论】:
-
您可以尝试this,而不是实施您自己的 OAuth 解决方案吗?他们甚至为您的网站提供了一个pull request,您可以复制和使用它。
-
@user3707125 ThanX 很多,授权工作正常。我通过收到的访问权限和秘密令牌成功地从 Withings“操场”获取了数据。但是这个 oauth 实现有 2 个问题:它在 2.0 版的 maven Central 中不可用,当我尝试获取数据(身体测量值)时,例如,我得到了空的响应正文,状态为:2554(错误的操作或错误的 Web 服务)。
-
我做错了什么?
OAuthRequest request = new OAuthRequest(Verb.GET, "https://wbsapi.withings.net/measure?action=getmeas", service); service.signRequest(accessToken, request); Response response = request.send(); return response.getBody(); -
我修复了它,将“.signatureType(SignatureType.QueryString)”添加到 OAuthService。