douniang3866
douniang3866
2019-04-04 21:13

在PHP中向RESTlet发送GET请求时NetSuite“INVALID_LOGIN错误”

已采纳

A few months ago I implemented a RESTlet solution that receives a POST request from a PHP script. I am now extending the solution to send a GET request to a RESTlet with a different ID. The issue is that the authentication is only successful when the request is sent to a URL without the query string. We need to pass the query string to the RESTlet in order for it to execute.

Appending the query string to the URL throws a 403 INVALID_LOGIN error, and calling the RESTlet without it throws an exception for a missing paramter (as expected).

private function setAuthentication() {
      $oauthNonce = md5(mt_rand());
      $oauthTimestamp = time();
      $baseString = $this->requestType."&".urlencode($this->url)."&".urlencode(
          "deploy=".$this->deployID
          ."&oauth_consumer_key=".$this->consumerKey
          ."&oauth_nonce=".$oauthNonce
          ."&oauth_signature_method=".$this->oauthSigMethod
          ."&oauth_timestamp=".$oauthTimestamp
          ."&oauth_token=".$this->tokenID
          ."&oauth_version=".$this->oauthVersion
          ."&realm=".$this->account
          ."&script=".$this->scriptID
        );
      $sigString = urlencode($this->consumerSecret).'&'.urlencode($this->tokenSecret);
      $signature = base64_encode(hash_hmac('sha1', $baseString, $sigString, true));
      $authHeader = "OAuth "
        . 'oauth_signature="' . rawurlencode($signature) . '", '
        . 'oauth_version="' . rawurlencode($this->oauthVersion) . '", '
        . 'oauth_nonce="' . rawurlencode($oauthNonce) . '", '
        . 'oauth_signature_method="' . rawurlencode($this->oauthSigMethod) . '", '
        . 'oauth_consumer_key="' . rawurlencode($this->consumerKey) . '", '
        . 'oauth_token="' . rawurlencode($this->tokenID) . '", '  
        . 'oauth_timestamp="' . rawurlencode($oauthTimestamp) . '", '
        . 'realm="' . rawurlencode($this->account) .'"';
        return $authHeader;
    }

public function callGetRestlet() {
      $this->requestType = 'GET';
        $authorizationHeader = $this->setAuthentication();
        $urlQueryAppend = http_build_query(array('id' => $this->queryString));
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->requestType);
      curl_setopt($ch, CURLOPT_URL, $this->url. '?&script='. $this->scriptID. '&deploy='. $this->deployID.'&realm=' . $this->account);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_TIMEOUT, 3);
      curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: '.$authorizationHeader,
            'Content-Type: application/json',
      ]);
      $response = array();
      $response['request'] = json_decode($this->queryString);
      $response['response']['body'] = json_decode(curl_exec($ch));
      $response['response']['code']  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      curl_close($ch);
      return $response;
    }

I know the credentials are okay as the RESTlet's event log shows the exception when the parameter isn't provided. The above throws the exception.

When the CURLOPT_URL is modified to include the querystring it throws the 403:

curl_setopt($ch, CURLOPT_URL, $this->url. '?&script='. $this->scriptID. '&deploy='. $this->deployID.'&realm=' . $this->account.'&'.$urlQueryAppend);

This code was slightly modified from an answer to a different question that asked about a POST request.

Is the error being thrown as a result of setting the request headers?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dronthpi05943 dronthpi05943 2年前

    Adding the id parameter to the base string after the deploy ID resolved the issue. I was adding it to the end, but in this case it looks like the order of the parameters matters.

    private function setAuthentication() {
       $oauthNonce = md5(mt_rand());
       $oauthTimestamp = time();
       $baseString = $this->requestType."&".urlencode($this->url)."&".urlencode(
            "deploy=".$this->deployID
            ."&id=".$this->queryString
            ."&oauth_consumer_key=".$this->consumerKey
            ."&oauth_nonce=".$oauthNonce
            ."&oauth_signature_method=".$this->oauthSigMethod
            ."&oauth_timestamp=".$oauthTimestamp
            ."&oauth_token=".$this->tokenID
            ."&oauth_version=".$this->oauthVersion
            ."&script=".$this->scriptID
          );
       $sigString = urlencode($this->consumerSecret).'&'.urlencode($this->tokenSecret);
       $signature = base64_encode(hash_hmac('sha1', $baseString, $sigString, true));
       $authHeader = "OAuth "
          . 'oauth_signature="' . rawurlencode($signature) . '", '
          . 'oauth_version="' . rawurlencode($this->oauthVersion) . '", '
          . 'oauth_nonce="' . rawurlencode($oauthNonce) . '", '
          . 'oauth_signature_method="' . rawurlencode($this->oauthSigMethod) . '", '
          . 'oauth_consumer_key="' . rawurlencode($this->consumerKey) . '", '
          . 'oauth_token="' . rawurlencode($this->tokenID) . '", '  
          . 'oauth_timestamp="' . rawurlencode($oauthTimestamp) . '", '
          . 'realm="' . rawurlencode($this->account) .'"';
         return $authHeader;
    }
    
    public function callGetRestlet() {
          $this->requestType = 'GET';
          $parameters = http_build_query(
            array(
              'script' => $this->scriptID,
              'deploy' => $this->deployID,
              'id' => $this->queryString,
            )
          );
          $authorizationHeader = $this->setAuthentication();
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->requestType);
          curl_setopt($ch, CURLOPT_URL, $this->url. '?'.$parameters);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_TIMEOUT, 6);
          curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Authorization: '.$authorizationHeader,
                'Content-Type: application/json',
          ]);
          $response = array();
          $response['request'] = $this->url. '?'.$parameters;
          $response['response']['body'] = json_decode(curl_exec($ch));
          $response['response']['code']  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
          curl_close($ch);
          return $response;
        }
    
    点赞 评论 复制链接分享