Walmart.io authentication issue - Could not authenticate in-request, auth signature

戏子无情 提交于 2020-08-10 18:48:49

问题


I am trying to link up with Walmart.io API to get some data from their resources. But I am stuck up in the first phase.

According to Walmart.io Quick Start Doc (https://walmart.io/docs/affiliate/quick-start-guide) I am supposed to follow following steps:

  1. Create an account with Walmart.io
  2. Create an application for Web Application
  3. Generate a certificate ( According to their guide there should be some feature to autogenerate the certificate, but I didn't find it)
  4. Upload public key to the application
  5. We will get consumer id and key version using which along with private key, we can make a request. We need to add additional headers that includes Signature and Timestamp too.

So, I did everything, but it still isn't working.

I am using Open SSL to generate private and public key as suggested by them: https://walmart.io/key-tutorial I tried avoiding -des3 so that it doesn't ask me for passphrase too, but it didn't work either.

Here is the script I tried with

curl --location --request GET 'https://developer.api.walmart.com/api-proxy/service/affil/product/v2/taxonomy' \
--header 'WM_SEC.KEY_VERSION: 2' \
--header 'WM_CONSUMER.ID: <Consumer_ID>' \
--header 'WM_CONSUMER.INTIMESTAMP: 1594389945813' \
--header 'WM_SEC.AUTH_SIGNATURE: W5PEHIew3LsnATk0zxJddeo416YEpMIjvk1b7lW9VMIZFx55erc/5df/FK9UtS5i48q057oASo0AX3SDd2hx+QSeyiX3FtLAgAgiZnGqQ6nJndySWgL5ih/GaUTXIC6dd048GFEZlC6axXdGoTWNzX9P0n/2DwLF9EtvMjdvjB1kum0z2xKz/lQGlvnjVkGK9sZdSUa5rfgxKSPi7ix+LRIJWYwt6mTKUlGz2vP1YjGcZ7gVwAs9o8iFC//0rHUWFwaEGrT0aZJtS7fvSFtKj5NRfemX4fwRO4cgBRxPWy9MRooQwXPmKxRP75PxHKTerv8X6HvRo0GdGut+2Krqxg==' \

And the response I get is

{
    "details": {
        "Description": "Could not authenticate in-request, auth signature :  Signature verification failed: affil-product, version: 2.0.0, env: prod",
        "wm_svc.version": "2.0.0",
        "wm_svc.name": "affil-product",
        "wm_svc.env": "prod"
    }
}

Hope someone gives me some insight into this problem.

Thanks in advance


回答1:


I've had this issue before, it looks like the format of the data you are trying to sign is incorrect.

In node, the content of the template string should look like this: ${consumerId}\n${timeStamp}\n${keyVersion}\n




回答2:


Turns out it was issue with generated Signature (That explains why it worked after I changed the script.

Thus here is the script that worked fine:

<?php

use GuzzleHttp\Psr7;
use GuzzleHttp\Exception\RequestException;

class Walmart{

    private $host;

    private $consumer_id;

    private $private_key_file;

    private $headers;

    private $sec_key_version;

    private $client;

    private $options;

    public function __construct($config){
        $this->host             = $config['host'];
        $this->consumer_id      = $config['consumer_id'];
        $this->private_key_file = $config['private_key_file'];
        $this->sec_key_version  = $config['sec_key_version'];

        $this->options = array();
        
        $this->client           = new GuzzleHttp\Client();
    }
    
    public function lookup_product($publisher_id='', $ids='', $upc='', $format='json'){
        $this->load_options();

        $url_params = array(
            'format' => $format,
        );

        if($publisher_id){
            $url_params['publisher_id'] = $publisher_id;
        }

        if($ids){
            $url_params['ids'] = $ids;
        }

        if($upc){
            $url_params['upc'] = $upc;
        }

        $query = http_build_query($url_params);

        $url = $this->host . '/product/v2/items?'.$query;
        try {
            $res = $this->client->request('GET', $url, $this->options);
            $body = $res->getBody();
            if($res->getStatusCode() == 200){
                return $this->response(false, json_decode($body, true));
            }else{
                return $this->response(array(
                    'title' => 'Unable to get products',
                    'stack' => $body,
                ));
            }
        } catch (RequestException $e) {
            $err = Psr7\str($e->getRequest());

            if ($e->hasResponse()) {
                $err .= Psr7\str($e->getResponse());
            }

            return $this->response(array(
                'title' => 'Unable to get products',
                'stack' => $err,
            ));
        }
    }

    private function load_options(){
        $timestamp = time()*1000;
        $this->options = array(
            'debug' => (defined("DEBUG") && DEBUG) ? true: false,
            'headers' => array(
                'WM_SEC.KEY_VERSION'        => $this->sec_key_version,
                'WM_CONSUMER.ID'            => $this->consumer_id,
                'WM_CONSUMER.INTIMESTAMP'   => $timestamp,
                'WM_SEC.AUTH_SIGNATURE'     => $this->get_signature($timestamp),
            )
        );
    }

    private function get_signature($timestamp){

        $message = $this->consumer_id."\n".$timestamp."\n".$this->sec_key_version."\n";

        $pkeyid = openssl_pkey_get_private("file://".$this->private_key_file);

        openssl_sign($message, $signature, $pkeyid, OPENSSL_ALGO_SHA256);

        $signature = base64_encode($signature);

        openssl_free_key($pkeyid);

        return $signature;
    }

    private function response($err, $data=false){
        return array(
            'error' => $err,
            'data' => $data,
        );
    }
}

Note: It uses guzzlehttp/guzzle library for HTTP Request



来源:https://stackoverflow.com/questions/62838147/walmart-io-authentication-issue-could-not-authenticate-in-request-auth-signat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!