c#でzaifのapiで認証が行えない
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 2,491
前提・実現したいこと
c#でzaifのapiで認証し「get_info」を実行したい。(詳細は以下参照)
ネット上にはC#のサンプルが無くて苦しんでます。
https://corp.zaif.jp/api-docs/trade-api/#method_get_info
発生している問題・エラーメッセージ
httpのリクエストの応答値が以下のようになってしまいます。
response = "{\"success\": 0, \"error\": \"invalid nonce parameter\"}"
該当のソースコード
class API_ZAIF_get_info
{
static readonly Uri endpointUri = new Uri("https://api.zaif.jp");
static readonly string apiKey = "APIキー";
static readonly string apiSecret = "APIシークレットキー";
public async Task<string> TaskStart()
{
var method = "POST";
var path = "/tapi";
var query = "";
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
var body = @"{
""nonce"": """ + timestamp + @""",
""method"": ""get_info""
}";
var data="";
data = HttpUtility.UrlEncode(body);
var hash = HASH.SignWithHMACSHA512(data, apiSecret);
using (var client = new HttpClient())
using (var request = new HttpRequestMessage(new HttpMethod(method), path + query))
using (var content = new StringContent(body))
{
client.BaseAddress = endpointUri;
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
request.Content = content;
request.Headers.Add("Key", apiKey);
request.Headers.Add("Sign", hash);
HttpResponseMessage message = await client.SendAsync(request);
if (message.IsSuccessStatusCode)
{
var response = await message.Content.ReadAsStringAsync();
WriteTextFile_ErrorInfo.write(request.ToString());
WriteTextFile_ErrorInfo.write(message.ToString());
return response;
}
else
{
WriteTextFile_ErrorInfo.write(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "API_ZAIF_get_info");
WriteTextFile_ErrorInfo.write(request.ToString());
WriteTextFile_ErrorInfo.write(message.ToString());
return "false";
}
}
}
}
C#に詳しい方がいたら、何処が悪いか教えて頂きたいです。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
WebClientを使った方法
// 参照に以下の2つを追加する。
// System.Security
// System.Web
//
// NuGetから以下1つのパッケージをインストールする。
// Newtonsoft.Json
using Newtonsoft.Json;
using System;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
namespace zaif_test
{
class Program
{
static readonly string API_TRADE_ENDPOINT = "https://api.zaif.jp/tapi";
static readonly string API_KEY = "***";
static readonly string API_SECRET = "***";
static void Main()
{
var wc = new WebClient();
// nonce用にunixtimeを用いる
var unixtime = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
// POSTするデータ
var data = HttpUtility.ParseQueryString(string.Empty);
data.Add("nonce", unixtime.ToString());
data.Add("method", "get_info");
// Sign を計算する
var hash = new HMACSHA512(new UTF8Encoding().GetBytes(API_SECRET)).ComputeHash(new UTF8Encoding().GetBytes(data.ToString()));
var sign = BitConverter.ToString(hash).ToLower().Replace("-", "");
// WebClientのヘッダにセットする
wc.Headers.Set("Key", API_KEY);
wc.Headers.Set("Sign", sign);
// POST実行
var res = wc.UploadValues(API_TRADE_ENDPOINT, data);
// 結果JSONのデシリアライズ
var json = JsonConvert.DeserializeObject(new UTF8Encoding().GetString(res));
// 結果を表示
Console.WriteLine(json);
}
}
}
HttpClientを使った方法
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace zaif_test_httpclient
{
class Program
{
static readonly string API_TRADE_ENDPOINT = "https://api.zaif.jp/tapi";
static readonly string API_KEY = "***";
static readonly string API_SECRET = "***";
static async Task<object> MyTask()
{
var httpClient = new HttpClient();
// nonce用にunixtimeを用いる
var unixtime = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
// POSTするデータ
var content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "nonce", unixtime.ToString() },
{ "method", "get_info" }
});
// Sign を計算する
var hash = new HMACSHA512(new UTF8Encoding().GetBytes(API_SECRET)).ComputeHash(new UTF8Encoding().GetBytes(await content.ReadAsStringAsync()));
var sign = BitConverter.ToString(hash).ToLower().Replace("-", "");
// HttpClientのヘッダにセットする
httpClient.DefaultRequestHeaders.Add("key", API_KEY);
httpClient.DefaultRequestHeaders.Add("Sign", sign);
// POST実行
var res = await httpClient.PostAsync(API_TRADE_ENDPOINT, content);
// 結果JSONのデシリアライズ
var json = JsonConvert.DeserializeObject(await res.Content.ReadAsStringAsync());
// 結果を返す
return json;
}
static void Main()
{
Task.Run(async () =>
{
var obj = await MyTask();
Console.WriteLine(obj);
}).Wait();
}
}
}
{
"success": 1,
"return": {
"funds": {
"jpy": 0.0,
"btc": 0.0,
"mona": 0.0
},
"deposit": {
"jpy": 0.0,
"btc": 0.0,
"mona": 0.0
},
"rights": {
"info": 1,
"trade": 1,
"withdraw": 1
},
"trade_count": 0,
"open_orders": 0,
"server_time": 1463503760
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/05/19 09:51
指定された方法で正しい応答を得ることはできました。
けれども「HttpRequestMessage」を用いた方法をご教授頂けないでしょうか。
2016/05/19 19:26