首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何签署OKEx POST API请求?

如何签署OKEx POST API请求?
EN

Stack Overflow用户
提问于 2021-12-22 14:48:19
回答 3查看 679关注 0票数 2

以下是这个问题How to sign an OKEx API request?的结果和一些答案:

代码语言:javascript
运行
复制
import hmac
import base64
import requests
import datetime
import json

from config import KEY, SECRET, PASS, ROOT_URL


def get_time():
    now = datetime.datetime.utcnow()
    t = now.isoformat("T", "milliseconds")
    return t + "Z"


def signature(timestamp, request_type, endpoint, body, secret):
    if body != '':
        body = json.dumps(body)
    message = str(timestamp) + str.upper(request_type) + endpoint + body
    print(message)
    mac = hmac.new(bytes(secret, encoding='utf-8'), bytes(message, encoding='utf-8'), digestmod='sha256')
    d = mac.digest()
    return base64.b64encode(d)


def get_header(request_type, endpoint, body):
    time = get_time()
    header = dict()
    header['CONTENT-TYPE'] = 'application/json'
    header['OK-ACCESS-KEY'] = KEY
    header['OK-ACCESS-SIGN'] = signature(time, request_type, endpoint, body, SECRET)
    header['OK-ACCESS-TIMESTAMP'] = str(time)
    header['OK-ACCESS-PASSPHRASE'] = PASS
    return header


def get(endpoint, body=''):
    url = ROOT_URL + endpoint
    header = get_header('GET', endpoint, body)
    return requests.get(url, headers=header)


def post(endpoint, body=''):
    url = ROOT_URL + endpoint
    header = get_header('POST', endpoint, body)
    return requests.post(url, headers=header)

其中KEY, SECRET, PASS分别是API密钥、密钥和传递短语;ROOT_URL'https://www.okex.com'

问题

GET请求工作非常正常,所以当我运行以下命令时,没有问题:

代码语言:javascript
运行
复制
ENDPOINT = '/api/v5/account/balance'
BODY = ''

response = get(ENDPOINT)
response.json()

但是,当我试图通过POST请求下订单时,如下所示:

代码语言:javascript
运行
复制
ENDPOINT = '/api/v5/trade/order'
BODY = {"instId":"BTC-USDT",
        "tdMode":"cash",
        "side":"buy",
        "ordType":"market",
        "sz":"1"}

response = post(ENDPOINT, body=BODY)
response.json()

我得到以下输出,即它不接受签名:

代码语言:javascript
运行
复制
{'msg': 'Invalid Sign', 'code': '50113'}

相关问题

在这个Can't figure out how to send a signed POST request to OKEx中提供了一个答案,但是它对我不起作用,因为我已经使用了建议的URL。在这里,Unable to send a post requests OKEX Invalid Signature提出了大致相同的问题,但是没有任何活动可能是由于格式引起的,所以我想我应该重新发布并详细说明。

OKEX文档

文档只需指定The API endpoints of Trade require authentication (https://www.okex.com/docs-v5/en/?python#rest-api-authentication-signature)。但是他们并没有提到这两种方法之间有什么区别。除此之外,就我所能看到的情况而言,我正在将所有必需的参数包括在post请求的正文中。

如果能对此提出意见,我将不胜感激。

非常感谢!

EN

回答 3

Stack Overflow用户

发布于 2022-03-18 08:01:21

我遇到了同样的问题,并解决了它。我使用了新的域名okex.com。这是我的密码。

代码语言:javascript
运行
复制
def set_userinfo(self):
    position_path = "/api/v5/account/set-position-mode"
    try:
        self.get_header("POST", position_path, {"posMode":"net_mode"})
        resp = requests.post(url=self.base_url+position_path, headers=self.headers, json={"posMode":"long_short_mode"}).json()
    except Exception as e:
        log.error("OK set_userinfo error={} type={}".format(f'{e}', f'{type(e)}'))

def get_header(self, request_type, endpoint, body=''):
    timestamp = self.get_time()
    self.headers["OK-ACCESS-TIMESTAMP"] = timestamp
    self.headers["OK-ACCESS-SIGN"] = self.signature(timestamp, request_type, endpoint, body)

def signature(self, timestamp, request_type, endpoint, body):
    if body != '':
        body = json.dumps(body)
    message = str(timestamp) + str.upper(request_type) + endpoint + body
    mac = hmac.new(bytes(self.secret_key, encoding='utf-8'), bytes(message, encoding='utf-8'), digestmod='sha256').digest()
    return base64.b64encode(mac)
票数 0
EN

Stack Overflow用户

发布于 2022-06-14 17:03:57

我也解决了同样的问题。签名()中的'body‘和get_header()中的’body‘都应该是json。因此,您应该添加以下代码:

代码语言:javascript
运行
复制
if str(body) == '{}' or str(body) == 'None':
    body = ''
else:
    body = json.dumps(body)
票数 0
EN

Stack Overflow用户

发布于 2022-11-14 04:11:00

我遇到了同样的问题,并使用下面的代码片段解决了这个问题,这个想法来自于https://stackoverflow.com/a/68115787/20497127,但是我通过添加POST功能做了一些修改

代码语言:javascript
运行
复制
APIKEY = "" # input key
APISECRET = "" #input secret
PASS = "" #input passphrase


BASE_URL = 'https://www.okx.com'

def send_signed_request(http_method, url_path, payload={}):
    def get_time():
        return dt.datetime.utcnow().isoformat()[:-3]+'Z'
    
    def signature(timestamp, method, request_path, body, secret_key):
        if str(body) == '{}' or str(body) == 'None':
            body = ''
        message = str(timestamp) + str.upper(method) + request_path + str(body)
        mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
        d = mac.digest()
        return base64.b64encode(d)
    
    # set request header
    def get_header(request='GET', endpoint='', body:dict=dict()):
        cur_time = get_time()
        header = dict()
        header['CONTENT-TYPE'] = 'application/json'
        header['OK-ACCESS-KEY'] = APIKEY
        header['OK-ACCESS-SIGN'] = signature(cur_time, request, endpoint , body, APISECRET)
        header['OK-ACCESS-TIMESTAMP'] = str(cur_time)
        header['OK-ACCESS-PASSPHRASE'] = PASS
        # demo trading: need to set x-simulated-trading=1, live trading is 0
        header['x-simulated-trading'] = '1'
        return header

    url = BASE_URL + url_path
    header = get_header(http_method, url_path, payload)
    print(url)
    print(header)
    if http_method == 'GET':
        response = requests.get(url, headers=header)
    elif http_method == 'POST':
        response = requests.post(url, headers=header, data=payload)
    return response.json()

# this will run get requests
res = send_signed_request("GET", "/api/v5/account/balance", payload={})

# this will run post requests
data = {
  "instId": "BTC-USDT",
  "tdMode": "cross",
  "side": "sell",
  "ccy":"USDT",
  "ordType": "limit",
  "px": "100000",
  "sz": "0.01"
}

res = send_signed_request("POST", "/api/v5/trade/order", payload=json.dumps(data))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70450871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档