当前位置: 代码迷 >> Android >> 从基于 OkHttp 的应用程序访问 WooCommerce Rest API 时出现问题
  详细解决方案

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

热度:30   发布时间:2023-08-04 12:30:39.0

我想构建一个可以使用 WooCommerce 提供的 Rest Api 与基于 WooCommerce 的站点交互的 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 客户端,效果很好。

此外,我无法根据给出的命令通过 curl 访问其余 api

有人能告诉我我做错了什么吗?

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

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

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

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

您可以找到一套完整的说明和 OAuth 1.0a 为 Android 实现的完整项目示例 有关使用上面链接的库的。 只要确保在使用提供的代码时确保考虑到您正在使用 OKHttp 的事实。 幸运的是,作者在说明中对代码进行了很好的注释,并记录了在使用 OkHttp 之类的东西时要进行的更改。

您可以使用并简单地编写一个拦截器,它负责处理文档中详述的“细节”部分

您还可以按照详述的分步指南生成您的 OAuth 签名和最后的 encodeUrl,然后将其传递给您的 http 客户端。 此过程涉及:(有关每个部分的详细规格,请参阅文档)

  1. 收集请求方法和URL
  2. 收集所有oauth_*参数并使用百分比编码和正确排序将它们编码为单个字符串。 例如(取自 WooCommerce Docs): 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)。

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

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

感谢回答我的问题。我也给了你赏金,感谢你增加我的知识。 尽管如此,我还是找到了解决这个问题的简单方法。

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

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

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(),以便在任何情况下都执行基本身份验证。

注意:这是一个 hack,只是为了避免在开发环境中 OAuth 身份验证的麻烦,并且根本不推荐在生产中使用。

  相关解决方案