代码之家  ›  专栏  ›  技术社区  ›  Subin Babu

Auth 1.0 oauth\u签名创建Android for magento API

  •  3
  • Subin Babu  · 技术社区  · 6 年前

    我使用以下身份验证作为标题调用Magento API,

    auth = "OAuth oauth_consumer_key=**********************,oauth_consumer_secret=****************,oauth_token=************,oauth_token_secret=**************,oauth_signature_method=HMAC-SHA1,oauth_timestamp=" + ConstantFunctions.GetTimeStamp() + ",oauth_nonce=" + ConstantFunctions.GetNonce() + ",oauth_signature=*******************) ;
    

    当我调用API时, 获取错误 oauth_problem=signature_invalid 。所有其他参数验证成功,但签名中出现错误, 我尝试使用以下代码生成签名,

         public static String GETHMACSHA1(String value, String key)
                throws UnsupportedEncodingException, NoSuchAlgorithmException,
                InvalidKeyException {
            String type = "HmacSHA1";
            SecretKeySpec secret = new SecretKeySpec(key.getBytes(), type);
            Mac mac = Mac.getInstance(type);
            mac.init(secret);
            byte[] bytes = mac.doFinal(value.getBytes());
            return bytesToHex(bytes);
        }
    
        private final static char[] hexArray = "0123456789abcdef".toCharArray();
    
        private static String bytesToHex(byte[] bytes) {
            char[] hexChars = new char[bytes.length * 2];
            int v;
            for (int j = 0; j < bytes.length; j++) {
                v = bytes[j] & 0xFF;
                hexChars[j * 2] = hexArray[v >>> 4];
                hexChars[j * 2 + 1] = hexArray[v & 0x0F];
            }
            return new String(hexChars);
        }
    

    我通过了 oauth_consumer_secret oauth_token_secret 作为获取签名的参数。但它仍然得到相同的错误。

    如何在android中生成签名,需要传递哪个值才能获得相同的签名?

    2 回复  |  直到 6 年前
        1
  •  5
  •   Subin Babu    5 年前

    我们不需要以auth的形式传递所有属性,改型本身可以处理这个问题,我们只需要传递CONSUMER\u密钥、CONSUMER\u SECRET、ACCESS\u令牌和TOKEN\u SECRET。

    通过以下方式 this

    ApiUtils类将是这样的,

    科特林

    class ApiUtils {
    companion object {
        fun getAPIService(): APIService? {
            val consumer = OkHttpOAuthConsumer(BuildConfig.CONSUMER_KEY, BuildConfig.CONSUMER_SECRET)
            consumer.setTokenWithSecret(BuildConfig.ACCESS_TOKEN, BuildConfig.TOKEN_SECRET)
            return RetrofitClient.getClient(BuildConfig.BASE_URL, consumer)?.create(APIService::class.java)
        }
    }
    

    }

    就业喜报

    public class ApiUtils {
    
        private ApiUtils() {
        }
    
        private static final String BASE_URL = BuildConfig.BASE_URL;
    
        public static APIService getAPIService() {
    
            OkHttpOAuthConsumer consumer = new OkHttpOAuthConsumer(BuildConfig.CONSUMER_KEY, BuildConfig.CONSUMER_SECRET);
            consumer.setTokenWithSecret(BuildConfig.ACCESS_TOKEN, BuildConfig.TOKEN_SECRET);
    
            OkHttpClient client = new OkHttpClient.Builder()
                    .addInterceptor(new SigningInterceptor(consumer))
                    .build();
            return RetrofitClient.getClient(BASE_URL, client).create(APIService.class);
        }
    }
    

    对于 改装客户端类

    科特林

        class RetrofitClient {
        companion object {
            private var retrofit: Retrofit? = null
            private val gSON = GsonBuilder()
                .setLenient()
                .create()
    
            fun getClient(baseUrl: String, consumer: OkHttpOAuthConsumer): Retrofit? {
                val logging = HttpLoggingInterceptor()
                if (BuildConfig.DEBUG) {
                    logging.level = HttpLoggingInterceptor.Level.BODY
                } else {
                    logging.level = HttpLoggingInterceptor.Level.NONE
                }
    
                val httpClient = OkHttpClient.Builder()
                httpClient.connectTimeout(60000, TimeUnit.SECONDS)
                httpClient.writeTimeout(120000, TimeUnit.SECONDS)
                httpClient.readTimeout(120000, TimeUnit.SECONDS)
                httpClient.retryOnConnectionFailure(true)
                httpClient.addInterceptor(SigningInterceptor(consumer))
                httpClient.addInterceptor { chain ->
                    val request = chain.request()
                    val requestBuilder = request.newBuilder()
                        .header(HEADER_CONTENT_TYPE_KEY, PreferenceHandler.getContentType())
                        .header(HEADER_ACCEPT_KEY, PreferenceHandler.getAcceptType())
                        .header(HEADER_CACHE_CONTROL_KEY, PreferenceHandler.getCacheControl())
                    val modifiedRequest = requestBuilder.build()
                    chain.proceed(modifiedRequest)
                }
    
                httpClient.addNetworkInterceptor(logging)
    
                if (retrofit == null) {
                    retrofit = Retrofit.Builder()
                        .baseUrl(baseUrl)
                        .addConverterFactory(GsonConverterFactory.create(gSON))
                        .client(httpClient.build())
                        .build()
                }
                return retrofit
            }
    
        }
    }
    

    Android java

    public class RetrofitClient {
    
        private static Retrofit retrofit = null;
    
        public static Retrofit getClient(String baseUrl,OkHttpClient client) {
            if (retrofit == null) {
                retrofit = new Retrofit.Builder()
                        .baseUrl(baseUrl)
                        .client(client)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
            }
            return retrofit;
        }
    }
    
        2
  •  1
  •   Muneef M    6 年前

    对于Oauth,我认为你不应该通过CS和TS。您需要连接一组URL编码的属性和参数来构造签名基字符串。请参考- devdocs。马根托。com/guides/v2.0/get-start/authentication/

    换句话说,SHA1中的一个参数将是一个编码的url 它应该是以HTTP方法开始的特定格式。

    enter image description here

    编码前,url应包含上述参数。

    我在android的Woocommerce API中进行了类似的Oauth身份验证。有关更多信息,请参考此要点url。

    https://gist.github.com/Muneefm/f4c08b2aa3accd57fa890156f74e619a

    在此检查中,方法调用 getLoginUrl() 。在其中,我连接了url。