我目前工作的一个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
任何一个可以帮我解决这个问题,我想改造本身来实现这个。
最后我找到了解决办法希望这将有助于其他一些
我经历的各种文件
1)Using the WooCommerce REST API – Introduction
3)Scribe
上述文件及源码指后我终于创建了做OAuth的1.0A的woocommerce HTTP Android的“一条腿”认证库
完整的描述在我的图书馆的阅读我部已添加
检查库在这里