LoginSignup
0
0

More than 1 year has passed since last update.

HttpClientを使ってNetSuiteのREST APIをコールする

Last updated at Posted at 2023-01-05

以前紹介した、NetSuiteのREST APIをPostmanから投げたのと同じように、C#からリクエストを投げたいと考えましたが、実装できるまで苦労したので記録用に。

前提

  • HttpClientを使ってリクエストを投げる
  • .NET Framework 4.7.2を使用
  • 認証に使うtokenなどはきちんと発行されている
  • TBA認証

0. 必要な値の準備

今回はサンプルとして、以下の値を使います。
値は以下のサイトから。

名前
URL https://123456.suitetalk.api.netsuite.com/services/rest/record/v1/employee/40
HttpMethod Get
TokenKey 2b0ce516420110bcbd36b69e99196d1b7f6de3c6234c5afb799b73d87569f5cc
TokenSecret c29a677df7d5439a458c063654187e3d678d73aca8e3c9d8bea1478a3eb0d295
ConsumerKey ef40afdd8abaac111b13825dd5e5e2ddddb44f86d5a0dd6dcf38c20aae6b67e4
ConsumerSecret d26ad321a4b2f23b0741c8d38392ce01c3e23e109df6c96eac6d099e9ab9e8b5
SignatureMethod HMAC-SHA256
Nonce (固定値ではない) fjaLirsIcCGVZWzBX0pg
Timestamp (固定値ではない) 1508242306
Version 1.0
Realm (AccountId) 123456

1. Signatureを作る

以下の資料を参考に、Signatureを作る処理をメソッドを実装していきます。

1-1. メソッドを作る

引数でHttpMethod, url, nonce, timestampを受け取ります。
必要に応じて引数は追加してください。

public static string ComputeSignature(HttpMethod httpMethod, string url, string tokenKey, string tokenSecret, string consumerKey, string consumerSecret, string signatureMethod, string nonce, string timestamp, string version)
{
  return "";
}

1-2. パラメータ無しのURLを取得

後で使うので、パラメータは取っておきます。
スキーマ (http、https) とホスト名は小文字である必要がありますが、今回は渡すときに小文字にするので処理は書いていません。

var baseUrl = url;
var getParams = "";
if (url.Contains("?"))
{
  var index = url.IndexOf("?");
  baseUrl = url.Substring(0, index);
  getParams = url.Substring(index + 1);
}

1-3. パラメータを用意

まずは必須の値をリストに入れます。

var paramList = new List<string>()
{
  "oauth_token=" + tokenKey,
  "oauth_consumer_key=" + consumerKey,
  "oauth_signature_method=" + signatureMethod,
  "oauth_nonce=" + nonce,
  "oauth_timestamp=" + timestamp,
  "oauth_version=" + version,
};

次に、URLのパラメータをparamListに追加していきます。

if (!string.IsNullOrEmpty(getParams))
{
  foreach (var param in getParams.Split('&'))
  {
    var parsed = param.Split('=');
    if (!string.IsNullOrEmpty(parsed[0]))
    {
      var name = Uri.UnescapeDataString(parsed[0]);
      var value = parsed.Length >= 2 ? Uri.UnescapeDataString(parsed[1]) : "";
      if (paramList.Any(x => x.StartsWith(value + "=")))
      {
        var removeParam = paramList.Where(x => x.StartsWith(value + "=")).FirstOrDefault();
        paramList.Remove(removeParam);
      }
      paramList.Add(name + "=" + value);
    }
  }
}

パラメータを昇順に並び替え、&でjoinしていきます。

paramList.Sort();
var baseParams = string.Join("&", paramList);

1-4. Base Stringを作る

HttpMethodは大文字で、URLとParamはパーセントエンコーディングします。

var baseString = httpMethod.ToString().ToUpper() + "&" + Uri.UnescapeDataString(baseUrl) + "&" + Uri.UnescapeDataString(baseParams);

baseStringには、以下の値が入っているはずです。

GET&https%3A%2F%2F123456.suitetalk.api.netsuite.com%2Fservices%2Frest%2Frecord%2Fv1%2Femployee%2F40&oauth_consumer_key%3Def40afdd8abaac111b13825dd5e5e2ddddb44f86d5a0dd6dcf38c20aae6b67e4%26oauth_nonce%3DfjaLirsIcCGVZWzBX0pg%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1508242306%26oauth_token%3D2b0ce516420110bcbd36b69e99196d1b7f6de3c6234c5afb799b73d87569f5cc%26oauth_version%3D1.0

1-5. Signatureを作る

HMACで署名を作るためのキーを作成します。

var key = Uri.UnescapeDataString(consumerSecret) + "&" + Uri.UnescapeDataString(tokenSecret);

続いて、HMAC-SHA256で署名を作成していきます。

var signature = "";
var encording = new System.Text.ASCIIEncording();
using (var hmacsha256 = new HMACSHA256(encording.GetBytes(key)))
{
  byte[] hashBaseString = hmacsha256.ComputeHash(encording.GetBytes(baseString));
  signature = Convert.ToBase64String(hashBaseString);
}

Signatureができたので、最後にreturnしてメソッドは完成です。

1-6. 完成したメソッド

public static string ComputeSignature(HttpMethod httpMethod, string url, string tokenKey, string tokenSecret, string consumerKey, string consumerSecret, string signatureMethod, string nonce, string timestamp, string version)
{
  // パラメータ無しのURLを取得
  var baseUrl = url;
  var getParams = "";
  if (url.Contains("?"))
  {
    var index = url.IndexOf("?");
    baseUrl = url.Substring(0, index);
    getParams = url.Substring(index + 1);
  }

  // 必須のパラメータを用意
  var paramList = new List<string>()
  {
    "oauth_token=" + tokenKey,
    "oauth_consumer_key=" + consumerKey,
    "oauth_signature_method=" + signatureMethod,
    "oauth_nonce=" + nonce,
    "oauth_timestamp=" + timestamp,
    "oauth_version=" + version,
  };

  // URLのパラメータをparamListに追加
  if (!string.IsNullOrEmpty(getParams))
  {
    foreach (var param in getParams.Split('&'))
    {
      var parsed = param.Split('=');
      if (!string.IsNullOrEmpty(parsed[0]))
      {
        var name = Uri.UnescapeDataString(parsed[0]);
        var value = parsed.Length >= 2 ? Uri.UnescapeDataString(parsed[1]) : "";
        if (paramList.Any(x => x.StartsWith(value + "=")))
        {
          var removeParam = paramList.Where(x => x.StartsWith(value + "=")).FirstOrDefault();
          paramList.Remove(removeParam);
        }
        paramList.Add(name + "=" + value);
      }
    }
  }

  // パラメータを昇順に並び替え、&でjoin
  paramList.Sort();
  var baseParams = string.Join("&", paramList);

  // HMAC-SHA256で署名を作成
  var key = Uri.UnescapeDataString(consumerSecret) + "&" + Uri.UnescapeDataString(tokenSecret);
  var signature = "";
  var encording = new System.Text.ASCIIEncording();
  using (var hmacsha256 = new HMACSHA256(encording.GetBytes(key)))
  {
    byte[] hashBaseString = hmacsha256.ComputeHash(encording.GetBytes(baseString));
    signature = Convert.ToBase64String(hashBaseString);
  }

  return signature;
}

2. リクエストのHeaderに詰めるAuthenticationを作る

Authenticationを作るためのメソッドを下記の通り作ります。

public static AuthenticationHeaderValue GenerateAuthenticationHeader(HttpMethod httpMethod, string url)
{
  var tokenKey = "2b0ce516420110bcbd36b69e99196d1b7f6de3c6234c5afb799b73d87569f5cc";
  var tokenSecret = "c29a677df7d5439a458c063654187e3d678d73aca8e3c9d8bea1478a3eb0d295";
  var consumerKey = "ef40afdd8abaac111b13825dd5e5e2ddddb44f86d5a0dd6dcf38c20aae6b67e4";
  var consumerSecret = "d26ad321a4b2f23b0741c8d38392ce01c3e23e109df6c96eac6d099e9ab9e8b5";
  var signatureMethod = "HMAC-SHA256";
  var nonce = "fjaLirsIcCGVZWzBX0pg"; // 本来は毎回違う値を用意
  var timestamp = "1508242306"; // 本来は毎回違う値を用意
  var version = "1.0";
  var realm = "123456";
  var signature = ComputeSignature(httpMethod, url, tokenKey, tokenSecret, consumerKey, consumerSecret, signatureMethod, nonce, timestamp, version);]

  var authString = @"realm=""" + Uri.UnescapeDataString(realm) + @""", " +
                   @"oauth_token=""" + Uri.UnescapeDataString(tokenKey) + @""", " +
                   @"oauth_consumer_key=""" + Uri.UnescapeDataString(consumerKey) + @""", " +
                   @"oauth_nonce=""" + Uri.UnescapeDataString(nonce) + @""", " +
                   @"oauth_timestamp=""" + Uri.UnescapeDataString(timestamp) + @""", " +
                   @"oauth_signature_method=""" + Uri.UnescapeDataString(signatureMethod) + @""", " +
                   @"oauth_version=""" + Uri.UnescapeDataString(version) + @""", " +
                   @"oauth_signature=""" + Uri.UnescapeDataString(signature) + @"""";

  return new AuthenticationHeaderValue("OAuth", authString);
}

3. リクエストを投げる

public static async Task<string> GetEmployeeAsync(string internalId)
{
  var url = "https://123456.suitetalk.api.netsuite.com/services/rest/record/v1/employee/" + internalId;
  var httpMethod = HttpMethod.Get;

  var content = "";
  using (var client = new HttpClient())
  {
    var request = neww HttpRequestMessage(httpMethod, url);
    request.Header.Authorization = GenerateAuthenticationHeader(httpMethod, url);
    var response = await client.SendAsync(request);
  
    content = await response.Content.ReadAsStringAsync();
  }

  return content;
} 

contentにPostmanで見たような値が入っていれば成功です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0