从基于OkHttp的应用访问WooCommerce Rest API时出现问题

时间:2018-09-16 16:40:44

标签: android woocommerce-rest-api

我想构建一个可以使用WooCommerce提供的Rest Api与基于WooCommerce的网站进行交互的android客户端

这是我的android代码。我正在使用OkHttp库进行联网。

public class MainActivity extends AppCompatActivity {
    OkHttpClient client;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String cred = Credentials.basic("ck_...","cs_...");

        OkHttpClient client = new OkHttpClient
                                    .Builder()
                                    .build();
        Request req = new Request
                            .Builder()
                .addHeader("Authorization",cred)

                .url("http://10.0.2.2:8080/woocom/wp-json/wc/v2/products")
                            .build();
        client.newCall(req).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d("api resp", "onFailure: ");
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d("Api resp", "onResponse: "+response.body().string());
            }
        });
    }
}

这是运行应用程序后的错误日志

com.example.android.woocommerceapiintegration D/Api resp: onResponse: {"code":"woocommerce_rest_cannot_view","message":"Sorry, you cannot list resources.","data":{"status":401}}

我在这里做错了什么。我试用了WooCommerce提供的NodeJS客户端,效果很好。

我也无法根据docs

中给出的命令通过curl访问rest api

有人可以告诉我我在做什么错吗?

更新:所选的答案是在生产环境中需要执行的操作,并且在技术上是正确的选择。如果您想避免在开发服务器上使用OAuth的麻烦,我已经单独回答了。

2 个答案:

答案 0 :(得分:1)

401代码指示您的连接存在授权问题。具体来说,您的问题是由您通过HTTP连接使用BasicAuth引起的。

WooCommerce REST API Documentation表示HTTPS连接仅支持BasicAuth,并且HTTP连接必须使用OAuth 1.0a“单腿式”身份验证来“确保”攻击者不会拦截您的凭据。 需要特别注意的是,即使使用OAuth 1.0a,HTTP连接也永远不会真正安全,强烈建议您将应用切换到安全的HTTPS连接。

同时,为了使代码正常工作,您必须为Android应用实现OAuth 1.0a身份验证方法。

您可以找到完整的说明集和适用于Android的OAuth 1.0a实现的完整项目示例here. GitHub Page has an excellent guide with step-by-step instructions使用上面链接的库。只需确保在使用提供的代码时,确保要考虑使用OKHttp的事实。幸运的是,作者对说明中的代码进行了很好的注释,并记下了使用OkHttp之类的代码时要进行的更改。

您可以使用Retrofit并只需编写一个拦截器,即可处理文档here.中详细介绍的“坚韧不拔”部分

您还可以按照WooCommerce Documentation here中详细介绍的逐步指南进行操作,以生成OAuth签名,最后生成encodeUrl,然后将其传递给http客户端。该过程涉及:(请参阅文档以获取每个部分的详细规格)

  1. 收集请求方法和URL
  2. 收集所有oauth_*参数,并使用百分比编码和正确的顺序将它们编码为单个字符串。例如(摘自WooCommerce文档): oauth_consumer_key=abc123&oauth_signature_method=HMAC-SHA1
  3. 通过连接1和2中的值来创建签名的基本字符串。例如:(再次从Docs中):

GET&http%3A%2F%2Fwww.example.com%2Fwp-json%2Fwc%2Fv2%2Forders&oauth_consumer_key%3Dabc123%26oauth_signature_method%3DHMAC-SHA1

  1. 最后使用HMAC-SHA1生成签名(也支持HMAC-SHA256)。

我个人建议第一种或第二种方法。 “无需重新发明轮子”。

编辑: 您可以查看this question,其中讨论了如何在Okdev的本地开发环境中使用自签名证书。

答案 1 :(得分:0)

感谢akseli回答了我的问题。我还向您颁发了赏金,感谢您对我的了解。尽管如此,我已经找到了解决此问题的简单方法。

我担心的是,在开发过程中,我们通常没有基于https的服务器,因此必须经历繁琐的基于OAuth的过程,无论如何该过程都不会用于生产,因为我们可能使用的服务器将是https已启用。

因此,要在http开发服务器上使用基本身份验证,您需要转到[your wordpress directory]/wp-content/woocommerce/includes/api。找出class-wc-rest-authentication.php。此类处理api身份验证。查找如下所示的authenticate函数

public function authenticate( $user_id ) {
    // Do not authenticate twice and check if is a request to our endpoint in the WP REST API.
    if ( ! empty( $user_id ) || ! $this->is_request_to_rest_api() ) {
        return $user_id;
    }

    if ( is_ssl() ) {
        return $this->perform_basic_authentication();
    }

    return $this->perform_oauth_authentication();
}

注释条件is_ssl并仅返回$ this-> perform_basic_authentication(),以便在任何情况下都执行基本身份验证。

注意:这是一种骇客程序,只是为了避免在开发环境中进行OAuth身份验证时遇到麻烦,并且完全不建议在生产环境中使用。