kotlin - 调用 Coinbase pro 沙盒 api 时,无效:401 Unauthorized。文本:"{"message":"invalid signature"}" Kotlin
问题描述
我想做的是调用 Coinbase 沙盒 API 来获取配置文件的所有帐户。
我正在关注官方文档https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_getaccounts
但不断收到此错误
Client request(https://api-public.sandbox.exchange.coinbase.com/accounts) invalid: 401 Unauthorized. Text: "{"message":"invalid signature"}"
我错过了什么吗?
suspend fun getTradingAccounts(): String {
val timestamp = getTimeStamp()
val response: String = client.get("https://api-public.sandbox.exchange.coinbase.com/accounts") {
headers {
append("Accept", "application/json")
append("Content-Type", "application/json")
append(
"cb-access-key",
"MY_KEY..."
)
append("cb-access-passphrase", "MY_PASSPHRASE....")
append("cb-access-sign", signMessage(
timestamp = timestamp,
method = "GET",
path = "https://api-public.sandbox.exchange.coinbase.com/accounts"
))
append("cb-access-timestamp", timestamp)
}
}
return response
}
private fun getTimeStamp(): String {
val time = LocalDateTime.now()
val zoneId = ZoneId.of("Europe/London")
val epoch = time.atZone(zoneId).toEpochSecond()
return epoch.toString()
}
@Throws(NoSuchAlgorithmException::class, InvalidKeyException::class)
private fun signMessage(timestamp: String, method: String, path: String): String {
val prehash = timestamp + method + path
val sha256_HMAC = Mac.getInstance("HmacSHA256")
val secretDecoded: ByteArray = Base64.getDecoder().decode("MY_API_KEY==")
val secret_key = SecretKeySpec(secretDecoded, "HmacSHA256")
sha256_HMAC.init(secret_key)
return Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(prehash.toByteArray()))
}
解决方案
正如我所见,在连接消息的组件时,您用于签署消息的代码不使用请求正文 JSON 字符串。这是我的函数版本,它为相同的输入返回与NodeJS 脚本中相同的字符串:
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.util.*
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
fun main() {
val result = sign(
secret = "TVlfQVBJX0tFWQ==",
timestampMs = System.currentTimeMillis(),
method = "POST",
requestPath = "/orders",
request = Req(
price = "1.0",
size = "1.0",
side = "buy",
product_id = "BTC-USD",
)
)
println(result)
}
@OptIn(ExperimentalSerializationApi::class)
fun sign(timestampMs: Long, method: String, requestPath: String, request: Req, secret: String): String {
val accessTimestamp = timestampMs / 1000.0
val message = "%.3f".format(accessTimestamp) + method + requestPath + Json.encodeToString(request)
val sha256HMAC = Mac.getInstance("HmacSHA256")
val key: ByteArray = Base64.getDecoder().decode(secret)
sha256HMAC.init(SecretKeySpec(key, "HmacSHA256"))
return Base64.getEncoder().encodeToString(
sha256HMAC.doFinal(message.toByteArray())
)
}
@Serializable
data class Req(val price: String, val size: String, val side: String, val product_id: String)
推荐阅读
- reactjs - 属性只能在对象上定义
- php - 可以在线运行 https://www.w3schools.com/js/tryit.asp?filename=tryjson_jsonp_php 但不能在我的电脑上运行
- pytorch - AttributeError:无法获取属性“_default_unk_index”
我在 google colab 中运行我的代码,但遇到了一些错误。
torch:1.1.0, torchtext:0.4.0,我更新了,但是没用
[2019-09-14 02:57:15,574 INFO] * src vocab size = 49766 [2019
- python - 使用 PIL.Image.new() 创建图像时“颜色”的含义是什么?
- svn - 无法搁置 - TortoiseSVN 1.12
- flutter - Flutter/Dart:无法调用小部件方法
- swift - 一旦发生某些事情,我如何退出功能?
- python - 在 Cloud Function 中使用 Cloud SQL (Postgres)
- google-chrome-extension - LevelDB 访问问题
- bixby - 需要强制 Bixby 解释——在语音中作为停顿而不是减号