java - Woocommerce api rest v2 签名不匹配

标签 java api woocommerce signature

我正在尝试调用 woocommerce 的 api rest,在这里你可以看到我调用它的代码,我有 oauth nonce、时间戳、 key 和 secret 并生成签名。我收到此错误。

{"errors":[{"code":"woocommerce_api_authentication_error","message":"Firma incorrecta - No coindicen las firmas"}]}

English: incorrect signature, signatures do not match.

public class Woocommerce {

private static String key = "ck_c6f7ea09138c------";
private static String secret = "cs_ed5c525f563dff-----";

private static final String HMAC_SHA1 = "HmacSHA1";

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

private static Base64 base64 = new Base64();

private static String getSignature(String url, String params)
        throws UnsupportedEncodingException, NoSuchAlgorithmException,
        InvalidKeyException {

    StringBuilder base = new StringBuilder();
    base.append("GET&");
    base.append(url);
    base.append("&");
    base.append(params);
    System.out.println("creating signature..." + base);

    byte[] keyBytes = (secret + "&").getBytes(ENC);

    SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA1);

    Mac mac = Mac.getInstance(HMAC_SHA1);
    mac.init(key);

    return new String(base64.encode(mac.doFinal(base.toString().getBytes(
            ENC))), ENC).trim();
}

public static void main(String[] args) throws ClientProtocolException,
        IOException, URISyntaxException, InvalidKeyException,
        NoSuchAlgorithmException {

    HttpClient httpclient = new DefaultHttpClient();
    List<NameValuePair> qparams = new ArrayList<NameValuePair>();
    // These params should ordered in key

    qparams.add(new BasicNameValuePair("oauth_consumer_key", key));
    qparams.add(new BasicNameValuePair("oauth_nonce", ""
            + (int) (Math.random() * 100000000)));
    qparams.add(new BasicNameValuePair("oauth_signature_method",
            "HMAC-SHA1"));
    qparams.add(new BasicNameValuePair("oauth_timestamp", ""
            + (System.currentTimeMillis() / 1000)));

    // generate the oauth_signature

    String signature = getSignature(
            URLEncoder.encode("www.buhoplace.net", ENC),
            URLEncoder.encode(URLEncodedUtils.format(qparams, ENC), ENC));
    // add it to params list
    qparams.add(new BasicNameValuePair("oauth_signature", signature));

    // generate URI which lead to access_token and token_secret.
    URI uri = URIUtils.createURI("http", "www.buhoplace.net", -1,
            "/wc-api/v2/products", URLEncodedUtils.format(qparams, ENC),
            null);

    System.out.println("url llamada" + uri);

    HttpGet httpget = new HttpGet(uri);
    // output the response content.
    System.out.println("Resultado de la llamada");

    HttpResponse response = httpclient.execute(httpget);
    HttpEntity entity = response.getEntity();
    if (entity != null) {
        InputStream instream = entity.getContent();
        int len;
        byte[] tmp = new byte[2048];
        while ((len = instream.read(tmp)) != -1) {
            System.out.println(new String(tmp, 0, len, ENC));
        }
    }
}

我该如何解决这个问题?

最佳答案

这是你的答案。仔细看这个片段,里面有一个woocommmerce的本地网站。在此请求 api 按钮中获取此本地站点的订单。 不要破坏签名参数的顺序。它附加在独特的系列中以生成正确的签名。

public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";
        private static final String CONSUMERKEY = "ck_cfaf32e212c68c7c66b9a8f43625af72";
        private static final String CONSUMERSECRET = "cs_814f422a33bc737d188cb6a05ea4897c";
        private static final String METHOD = "HMAC-SHA1";
        private static final String URL = "http://192.168.1.21/wordpress/wc-api/v2/orders";
        private static final String PARAMNAME_KEY = "oauth_consumer_key";
        private static final String PARAMNAME_SECRET = "oauth_consumer_secret";
        private static final String PARAMNAME_NONCE = "oauth_nonce";
        private static final String PARAMNAME_TIMESTAMP = "oauth_timestamp";
        private static final String PARAMNAME_SIGNATURE = "oauth_signature";
        private static final String PARAMNAME_SIGNATURE_METHOD = "oauth_signature_method";

        /**
         * Returns a new instance of this fragment for the given section number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

        Button bRequest, bClear;
        TextView tvResponse;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container,
                    false);
            bRequest = (Button) rootView.findViewById(R.id.button1);
            bClear = (Button) rootView.findViewById(R.id.button2);
            bRequest.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    new TestApi().execute();
                }
            });
            bClear.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    tvResponse.setText("");
                }
            });
            tvResponse = (TextView) rootView.findViewById(R.id.textView1);
            return rootView;
        }

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            ((MainActivity) activity).onSectionAttached(getArguments().getInt(
                    ARG_SECTION_NUMBER));
        }

        public String getSignature() {
            ArrayList<String> names = new ArrayList<String>();
            names.add(PARAMNAME_KEY);
            names.add(PARAMNAME_TIMESTAMP);
            names.add(PARAMNAME_NONCE);
            names.add(PARAMNAME_SIGNATURE_METHOD);
            return null;
        }

        class TestApi extends AsyncTask<Void, Void, Void> {
            ProgressDialog d;
            JSONParser jparser = new JSONParser();
            JSONObject response;
            List<NameValuePair> parameters;

            @Override
            protected Void doInBackground(Void... params) {
                String timestamp = System.currentTimeMillis() / 1000 + "";
                String nonce =  (Math.random() * 100000000) + "";
                parameters = new ArrayList<NameValuePair>();
                parameters.add(new BasicNameValuePair("oauth_consumer_key",
                        CONSUMERKEY));
                // parameters.add(new
                // BasicNameValuePair("oauth_consumer_secret",
                // CONSUMERSECRET));
                parameters.add(new BasicNameValuePair("oauth_timestamp",
                        timestamp));
                parameters.add(new BasicNameValuePair("oauth_nonce",
                        nonce));
                parameters.add(new BasicNameValuePair("oauth_signature_method",
                        "HMAC-SHA1"));
                String encoded_base_url = "GET&" + URLEncoder.encode(URL) + "&";
                Log.d("encoded url", encoded_base_url);
                StringBuilder builder = new StringBuilder();
                builder.append(PARAMNAME_KEY + "=" + CONSUMERKEY + "&");
                // builder.append(PARAMNAME_SECRET + "=" + CONSUMERSECRET +
                // "&");

                builder.append(PARAMNAME_NONCE + "="
                        + nonce + "&");

                builder.append(PARAMNAME_SIGNATURE_METHOD + "=" + METHOD + "&");
                builder.append(PARAMNAME_TIMESTAMP + "=" + timestamp);
                String str = builder.toString();
                str = URLEncoder.encode(str);
                Log.d("prepared string", str);
                String signature = encoded_base_url + str;
                String encoded = "";
                try {
                    Mac mac = Mac.getInstance(METHOD);
                    byte[] key = CONSUMERSECRET.getBytes("utf-8");
                    SecretKey secretKey = new SecretKeySpec(key, METHOD);
                    mac.init(secretKey);
                    byte[] signaturebytes = mac.doFinal(signature
                            .getBytes("utf-8"));
                    encoded = Base64.encodeToString(signaturebytes,
                            Base64.DEFAULT).trim();

                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                Log.d("signature", encoded);
                parameters.add(new BasicNameValuePair(PARAMNAME_SIGNATURE,
                        encoded));
                response = jparser.makeHttpRequest(
                        URL,
                        "GET", parameters);
                return null;
            }

            @Override
            protected void onPreExecute() {
                // TODO Auto-generated method stub
                super.onPreExecute();
                d = new ProgressDialog(getActivity());
                d.show();
            }

            @Override
            protected void onPostExecute(Void result) {
                // TODO Auto-generated method stub
                super.onPostExecute(result);
                d.dismiss();
                tvResponse.setText(response.toString());
            }

        }
    }

url应该是wordpress商店的完整url。

关于java - Woocommerce api rest v2 签名不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27589511/

相关文章:

api - Jetty - 如何仅允许来自特定域的请求

php - 有条件地向购物车添加费用

php - 如果在 Woocommerce 中购买了特定产品类别中的任何商品,则将产品设置为仅购买一次或不购买

java - 如何模拟测试下方法调用的方法

php - SQL-PHP 从 URL 末尾抓取信息并与数据库中的行进行比较

java - 为什么可以在没有 getter 的情况下访问字段?

javascript - 无法使用 jQuery 访问 API

php - WooCommerce:如何在 Hook 操作中排除特定页面

java - 如何在recyclerView中自动播放歌曲?

java - 参数未传递给过程