如何利用改造为Android的woocommerce API来实现OAuth的1.0A

问题描述 投票:7回答:1

我目前工作的一个woocommerce API,我需要使用改装的API集成。该网站是在HTTP因此HTTP基本身份验证无法通过普通的HTTP被用作键很容易受到拦截。该API使用OAuth 1.0a的“一条腿”的认证,以确保您的API密钥无法被截获。我已经通过了this artical了解哪些OAuth的methord要在HTTP使用。

我一直在使用Scribe成功实施的API,但我想要实现使用改装的API,谷歌上搜索,我发现拦截器是杰克沃顿Oauth1SigningInterceptor后。

所以我实现了,在改造的身份验证,但API调用返回

{"code":"woocommerce_rest_cannot_view","message":"Sorry, you cannot list resources.","data":{"status":401}}

相同的API,如果我打电话使用划线返回成功响应

下面的是我如何调用API

BasicAuthInterceptor.java(从杰克沃顿Oauth1SigningInterceptor修改)

public class BasicAuthInterceptor implements Interceptor {
private static final Escaper ESCAPER = UrlEscapers.urlFormParameterEscaper();
private static final String OAUTH_CONSUMER_KEY = "oauth_consumer_key";
private static final String OAUTH_NONCE = "oauth_nonce";
private static final String OAUTH_SIGNATURE = "oauth_signature";
private static final String OAUTH_SIGNATURE_METHOD = "oauth_signature_method";
private static final String OAUTH_SIGNATURE_METHOD_VALUE = "HMAC-SHA1";
private static final String OAUTH_TIMESTAMP = "oauth_timestamp";

private static final String OAUTH_VERSION = "oauth_version";
private static final String OAUTH_VERSION_VALUE = "1.0";

private final String consumerKey;
private final String consumerSecret;

private final Random random;
private BasicAuthInterceptor(String consumerKey, String consumerSecret, Random random) {
    this.consumerKey = consumerKey;
    this.consumerSecret = consumerSecret;

    this.random = random;
}
@Override
public Response intercept(Chain chain) throws IOException {
    return chain.proceed(signRequest(chain.request()));
}

public Request signRequest(Request request) throws IOException {
    byte[] nonce = new byte[32];
    random.nextBytes(nonce);
    String oauthNonce = ByteString.of(nonce).base64().replaceAll("\\W", "");
    String oauthTimestamp = String.valueOf(System.currentTimeMillis());

    String consumerKeyValue = ESCAPER.escape(consumerKey);


    SortedMap<String, String> parameters = new TreeMap<>();
    parameters.put(OAUTH_CONSUMER_KEY, consumerKeyValue);

    parameters.put(OAUTH_NONCE, oauthNonce);
    parameters.put(OAUTH_TIMESTAMP, oauthTimestamp);
    parameters.put(OAUTH_SIGNATURE_METHOD, OAUTH_SIGNATURE_METHOD_VALUE);
    parameters.put(OAUTH_VERSION, OAUTH_VERSION_VALUE);

    HttpUrl url = request.url();
    for (int i = 0; i < url.querySize(); i++) {
        parameters.put(ESCAPER.escape(url.queryParameterName(i)),
                ESCAPER.escape(url.queryParameterValue(i)));
    }


    RequestBody requestBody = request.body();
    Buffer body = new Buffer();

    if (requestBody != null) {
        requestBody.writeTo(body);
    }

    while (!body.exhausted()) {
        long keyEnd = body.indexOf((byte) '=');
        if (keyEnd == -1) throw new IllegalStateException("Key with no value: " + body.readUtf8());
        String key = body.readUtf8(keyEnd);
        body.skip(1); // Equals.

        long valueEnd = body.indexOf((byte) '&');
        String value = valueEnd == -1 ? body.readUtf8() : body.readUtf8(valueEnd);
        if (valueEnd != -1) body.skip(1); // Ampersand.

        parameters.put(key, value);
    }

    Buffer base = new Buffer();
    String method = request.method();
    base.writeUtf8(method);
    base.writeByte('&');
    base.writeUtf8(ESCAPER.escape(request.url().newBuilder().query(null).build().toString()));
    base.writeByte('&');

    boolean first = true;
    for (Map.Entry<String, String> entry : parameters.entrySet()) {
        if (!first) base.writeUtf8(ESCAPER.escape("&"));
        first = false;
        base.writeUtf8(ESCAPER.escape(entry.getKey()));
        base.writeUtf8(ESCAPER.escape("="));
        base.writeUtf8(ESCAPER.escape(entry.getValue()));
    }

    String signingKey =
            ESCAPER.escape(consumerSecret);// + "&" + ESCAPER.escape(accessSecret);

    SecretKeySpec keySpec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
    Mac mac;
    try {
        mac = Mac.getInstance("HmacSHA1");
        mac.init(keySpec);
    } catch (NoSuchAlgorithmException | InvalidKeyException e) {
        throw new IllegalStateException(e);
    }
    byte[] result = mac.doFinal(base.readByteArray());
    String signature = ByteString.of(result).base64();

    String authorization = "OAuth "
            + OAUTH_CONSUMER_KEY + "=\"" + consumerKeyValue + "\", "
            + OAUTH_NONCE + "=\"" + oauthNonce + "\", "
            + OAUTH_SIGNATURE + "=\"" + ESCAPER.escape(signature) + "\", "
            + OAUTH_SIGNATURE_METHOD + "=\"" + OAUTH_SIGNATURE_METHOD_VALUE + "\", "
            + OAUTH_TIMESTAMP + "=\"" + oauthTimestamp + "\", "

            + OAUTH_VERSION + "=\"" + OAUTH_VERSION_VALUE + "\"";

    Log.d("message","--"+authorization);


    return request.newBuilder()
            .addHeader("Authorization", authorization)
    .addHeader("Content-Type", "application/json;charset=UTF-8")
    .addHeader("Accept", "application/json;versions=1")
            .build();
}

public static final class Builder {
    private String consumerKey;
    private String consumerSecret;

    private Random random = new SecureRandom();


    public Builder consumerKey(String consumerKey) {
        if (consumerKey == null) throw new NullPointerException("consumerKey = null");
        this.consumerKey = consumerKey;
        return this;
    }

    public Builder consumerSecret(String consumerSecret) {
        if (consumerSecret == null) throw new NullPointerException("consumerSecret = null");
        this.consumerSecret = consumerSecret;
        return this;
    }



    public Builder random(Random random) {
        if (random == null) throw new NullPointerException("random == null");
        this.random = random;
        return this;
    }



    public BasicAuthInterceptor build() {
        if (consumerKey == null) throw new IllegalStateException("consumerKey not set");
        if (consumerSecret == null) throw new IllegalStateException("consumerSecret not set");

    }
}
}

远程API调用

public final class RemoteApiCalls {
private static final String TAG = "RemoteApiCalls";

public static final class Builder {
    RemoteRetrofitInterfaces mService;
    Retrofit mRetrofit;

    public Builder remoteApiCall(String url,Context mContext) {
        return remoteApiCall(mContext,url, 40, 40, 40);
    }

    BasicAuthInterceptor oauth1 = new BasicAuthInterceptor.Builder()
            .consumerKey("keyhere")//i have added keys
            .consumerSecret("secert here")//i have added secertkeys
            .build();

    public Builder remoteApiCall(Context mContext, String url, int connectionTimeout, int readTimeout, int writeTimeout) {

         HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS).addInterceptor(interceptor).addInterceptor(oauth1)
                .build();

        mRetrofit = new Retrofit.Builder()
                .baseUrl(url).addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();
        mService = mRetrofit.create(RemoteRetrofitInterfaces.class);


        return this;
    }



    public void getProductCatogry()

    {

        Call<ProductCategoryResponse> mApiCall = mService.getListCategory();
        mApiCall.enqueue(new Callback<ProductCategoryResponse>() {
            @Override
            public void onResponse(Call<ProductCategoryResponse> call, Response<ProductCategoryResponse> response) {

                if (response.isSuccessful()) {


                } else {

                }
            }

            @Override
            public void onFailure(Call<ProductCategoryResponse> call, Throwable t) {
t.printStackTrace();
            }


        });

    }

}

}

remote retrofit interfaces.Java

public interface RemoteRetrofitInterfaces {

@GET("products")
Call<ProductCategoryResponse> getListCategory();
}

在主要活动我打电话

 new RemoteApiCalls.Builder().remoteApiCall("http://mywebsite.com/wp-json/wc/v1/",getApplicationContext()).getProductCatogry();

还是我得到的401错误

{"code":"woocommerce_rest_cannot_view","message":"Sorry, you cannot list resources.","data":{"status":401}}

使用呜商业版本是2.6.4 API版本为v1

任何一个可以帮我解决这个问题,我想改造本身来实现这个。

android api oauth retrofit2 woocommerce-rest-api
1个回答
6
投票

最后我找到了解决办法希望这将有助于其他一些

我经历的各种文件

1)Using the WooCommerce REST API – Introduction

2)woocommerce-rest-api-docs

3)Scribe

4)scribe:1.3.5

上述文件及源码指后我终于创建了做OAuth的1.0A的woocommerce HTTP Android的“一条腿”认证库

完整的描述在我的图书馆的阅读我部已添加

检查库在这里

WoocommerceAndroidOAuth1 LIBRARY

© www.soinside.com 2019 - 2024. All rights reserved.