Nokia / Withings API返回342

时间:2018-03-09 13:40:30

标签: withings

我正在尝试调用Nokias Get Body Measures api

https://api.health.nokia.com/measure?action=getmeas

今天,我已按照https://developer.health.nokia.com/api的所有步骤进行操作 但最后我得到了下面提到的342错误

{"status":342,"error":"The signature (using Oauth) is invalid"}

---编辑---- 我需要为Get Body Measures API(https://developer.health.nokia.com/api/doc#api-Measure-get_measure

构建api

诺基亚apis使用OAuth 1.0。我有消费者密钥,秘密&用户身份验证令牌&秘密密钥。

以下是我用来生成OAuth签名的代码,但诺基亚apis抱怨它无效。

我不确定下面提到的代码中有什么问题。请帮忙!

由于

package org.nokia.oauth.OAuthSignature;

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.net.URI;

import java.net.URISyntaxException;

import java.net.URLEncoder;
import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.util.ArrayList;

import java.util.List;


import javax.crypto.Mac;

import javax.crypto.SecretKey;

import javax.crypto.spec.SecretKeySpec;


import org.apache.commons.codec.binary.Base64;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;

public class OAuthSignatureGenerator {

    private static String key = "___";
    private static String secret = "___";


    private static final String HMAC_SHA1 = "HmacSHA1";

    private static final String ENC = "UTF-8";

    private static Base64 base64 = new Base64();

    public static void main()
            throws Exception {

    String nonce = genNonce(32);

        List<NameValuePair> qparams = new ArrayList<NameValuePair>();
        qparams.add(new BasicNameValuePair("action", "getmeas"));
        qparams.add(new BasicNameValuePair("oauth_consumer_key", key));
        qparams.add(new BasicNameValuePair("oauth_nonce", "" +nonce));
        qparams.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
        qparams.add(new BasicNameValuePair("oauth_timestamp", "" + (System.currentTimeMillis() / 1000)));
        qparams.add(new BasicNameValuePair("oauth_token","***********"));

        qparams.add(new BasicNameValuePair("oauth_version", "1.0"));

        qparams.add(new BasicNameValuePair("userid","************"));



        String url = "http://api.health.nokia.com/measure";


    StringBuilder base = new StringBuilder();
        base.append("GET&");
        base.append(URLEncoder.encode(url, ENC));
        base.append("&");
        base.append(URLEncoder.encode(URLEncodedUtils.format(qparams, ENC), ENC));

        String sign = sign(base.toString());

    List<NameValuePair> qparams1 = new ArrayList<NameValuePair>();
    qparams1.add(new BasicNameValuePair("action", "getmeas"));
        qparams1.add(new BasicNameValuePair("oauth_consumer_key", key));
        qparams1.add(new BasicNameValuePair("oauth_nonce", "" + nonce));
        qparams1.add(new BasicNameValuePair("oauth_signature",URLEncoder.encode(new1,ENC)));

        qparams1.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
        qparams1.add(new BasicNameValuePair("oauth_timestamp", "" + (System.currentTimeMillis() / 1000)));
        qparams1.add(new BasicNameValuePair("oauth_token","4995c0d05916b42f3e260554dd825bc3740997067ec223e7e81eb3b2dc36"));

        qparams1.add(new BasicNameValuePair("oauth_version", "1.0"));
        qparams1.add(new BasicNameValuePair("userid","10964064"));

        ub.addParameters(qparams1);
        URLEncodedUtils.format(qparams, ENC), null);
        URI uri = ub.build();
        System.out.println("URL with OAuth signature => "
                + uri.toString());
    }





    public static String sign(String signatureBaseString) {
        try {
          Mac mac = Mac.getInstance(HMAC_SHA1);
          String oauth_token = "****";
            byte[] keyBytes = (secret + "&" + oauth_token ).getBytes("UTF-8");

            SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA1);
          mac.init(key);
          byte[] text = signatureBaseString.getBytes("UTF-8");
          byte[] signatureBytes = mac.doFinal(text);
          signatureBytes = Base64.encodeBase64(signatureBytes);
          String signature = new String(signatureBytes, "UTF-8");


            System.out.println("signature base: " + signatureBaseString);
            System.out.println("signature: " + signature);


          return signature;
        }
        catch (NoSuchAlgorithmException e) {
          throw new IllegalStateException(e);
        }
        catch (InvalidKeyException e) {
          throw new IllegalStateException(e);
        }
        catch (UnsupportedEncodingException e) {
          throw new RuntimeException(e);
        }
    }

    public static String genNonce(int length) {
    String text = "";
    String possible =  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for(int i =0 ; i < length;i++) {
      text += possible.charAt((int)Math.floor(Math.random() * possible.length()));
    }

    return text;
    }
    }

2 个答案:

答案 0 :(得分:0)

再过几次白发后,我发现了这个问题!! 问题是我正在编写oauth签名&amp;当在url中使用它时会再次编码,因此问题

//qparams1.add(new BasicNameValuePair("oauth_signature",URLEncoder.encode(new1,ENC)));

qparams1.add(new BasicNameValuePair("oauth_signature","new1"));

上述变化解决了这个问题。

但是,我有新问题为此api添加过滤器。 这个api有多个过滤器,如下所述&amp;当我添加它们时,我会回到342 Oauth错误

{"status":342,"error":"The signature (using Oauth) is invalid"}

// filters for start & end date and measure type
qparams1.add(new BasicNameValuePair("startdate", "1394444124"));
qparams1.add(new BasicNameValuePair("enddate", "1514764800"));
qparams1.add(new BasicNameValuePair("meastype", "1"));

我已尝试在生成签名时添加此参数的所有组合,将其从签名gen字符串中排除。但没有运气。

请帮帮我......

我不知道如何联系诺基亚人!

答案 1 :(得分:0)

我真的不知道你的代码有什么问题。但我可以分享我的代码,它做同样的事情并且有效。我使用

consumer.sign(uri)

从路标库中签署GET请求。这段代码可能有点hacky。

import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import oauth.signpost.http.HttpRequest;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class HealthRequests {

    private String consumer_key,consumer_secret, access_token, access_secret, uri,signed_uri  ;

    OAuthConsumer consumer;

    private HttpClient httpclient;
    private HttpGet httpget;


    public HealthRequests(){
        this.consumer_key = APIKeys.consumer_key;
        this.consumer_secret = APIKeys.consumer_secret;
        this.access_token = APIKeys.access_token;
        this.access_secret= APIKeys.access_token_secret;

        this.uri = "https://api.health.nokia.com/measure?action=getmeas";
        this.signed_uri = null;

        this.consumer = new CommonsHttpOAuthConsumer(consumer_key,consumer_secret);

        this.httpclient = HttpClientBuilder.create().build();
        this.httpget = new HttpGet(uri);

        consumer.setTokenWithSecret(access_token, access_secret);
    }




    // String startDate,String endDate,String lastUpdate
    public void getBodyMeasures () throws IOException {

        signURL();

        request();
    }

    public void getBodyMeasures (long lastUpdate) throws IOException {

        this.consumer.setTokenWithSecret(access_token, access_secret);

        this.uri+= "&lastupdate="+lastUpdate;

        this.signURL();

        this.request();
    }

    public void getBodyMeasures (long startDate, long endDate) throws IOException {

        this.consumer.setTokenWithSecret(access_token, access_secret);

        this.uri += "&startdate="+startDate+"&enddate="+endDate;

        this.signURL();

        this.request();
    }


    private void signURL(){

        try {
            this.signed_uri = consumer.sign(uri);
            this.httpget = new HttpGet(signed_uri);
        } catch (OAuthMessageSignerException ex) {
            Logger.getLogger(HttpRequest.class.getName()).log(Level.SEVERE,       null, ex);
        } catch (OAuthExpectationFailedException ex) {
            Logger.getLogger(HttpRequest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (OAuthCommunicationException ex) {
            Logger.getLogger(HttpRequest.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void request () throws IOException{
        HttpResponse response = httpclient.execute(httpget);
        System.out.println(response.getStatusLine().toString());
        HttpEntity entity = response.getEntity();
        System.out.println();
        System.out.println(EntityUtils.toString(entity));
    }
}