在 Python 中的 DocuSign 中获取令牌
Posted
技术标签:
【中文标题】在 Python 中的 DocuSign 中获取令牌【英文标题】:Get tokens in DocuSign in Python 【发布时间】:2020-04-27 06:07:33 【问题描述】:我在一个项目中工作,我正在尝试获取访问令牌以使用 DocuSign API,但获取 oauth 用户信息的调用不起作用。
认证类型:JWT Grant Python SDK:docusign-python-client代码:
class BaseDocusign:
api_client = None
_token_received = False
expiresTimestamp = 0
account = None
def __init__(self):
BaseDocusign.api_client = ApiClient()
def token_is_expired(self):
current_time = int(round(time.time()))
return (current_time + DOCUSIGN_EXPIRE_TIME - 10) > BaseDocusign.expiresTimestamp
def check_token(self):
if not BaseDocusign._token_received or self.token_is_expired():
self.update_token()
def update_token(self):
client = BaseDocusign.api_client
client.request_jwt_user_token(
DOCUSIGN_CLIENT_ID,
DOCUSIGN_ACCOUNT_ID,
DOCUSIGN_AUTH_SERVER,
DOCUSIGN_PRIVATE_KEY,
DOCUSIGN_EXPIRE_TIME
)
if BaseDocusign.account is None:
account = self.get_account_info(client)
print account
BaseDocusign._token_received = True
BaseDocusign.expiresTimestamp = (int(round(time.time())) + DOCUSIGN_EXPIRE_TIME)
def get_account_info(self, client):
client.host = DOCUSIGN_AUTH_SERVER
response = client.call_api("/oauth/userinfo", "GET", response_type="object")
if len(response) > 1 and 200 > response[1] > 300:
raise Exception("can not get user info: %d".format(response[1]))
accounts = response[0]['accounts']
target = target_account_id
if target is None or target == "FALSE":
# Look for default
for acct in accounts:
if acct['is_default']:
return acct
# Look for specific account
for acct in accounts:
if acct['account_id'] == target:
return acct
raise Exception("User does not have access to account target\n")
当我运行它时:
a = BaseDocusign()
a.update_token()
生成访问令牌:
"access_token":"eyJ0eXAiOiJNVCIsImFsZyI6IlJTMjU2Iiwia2lkIjoiNjgxODVmZjEtNGU1MS00Y2U5LWFmMWMtNjg5ODEyMjAzMzE3In0.AQkAAAABAAsADQAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwIgAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwBwAAq89LFJXXSAgAAOvyWVeV10gLAB8AAABodHRwczovL2FjY291bnQtZC5kb2N1c2lnbi5jb20vDAAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwGAABAAAABQAAABIAAQAAAAYAAABqd3RfYnI.f_XW63iL5ABts-gq48ciWKQnaYyNiIEG9rC_CpnyWo0Hzf-B_G3hIRUWJzD1Yiyyy4pKm_8-zoalsoqANcMeXsjwBTCMlXIhc216ZWa6nHR6CheRbfTHM6bJ1LKwRdmnpwLywu_qiqrEwEOlZkwH_GzSSP9piUtpCmhgdZY1GFnG2u9JU_3jd8nKN87PE_cn2sjD3fNMRHQXjnPeHPyBZpC171TyuEvQFKCbV5QOwiVXmZbE9Aa_unC-xXvvJ2cA3daVaUBHoasXUxo5CZDNb9aDxtQkn5GCgQL7JChL7XAfrgXAQMOb-rEzocBpPJKHl6chBNiFcl-gfFWw2naomA","token_type":"Application","expires_in":28800
但是当尝试获取账户信息时,调用失败:
"error":"internal_server_error","reference_id":"f20e360c-185d-463e-9f0b-ce95f38fe711"
为此,我调用了get_account_info
函数,它调用了端点oauth/userinfo
,但调用失败了。
response = client.call_api("/oauth/userinfo", "GET", response_type="object")
# Response: "error":"internal_server_error","reference_id":"f20e360c-185d-463e-9f0b-ce95f38fe711"
要做到这一点example,我需要变量account_id
,根据这个例子,get_account_info
函数得到它。
我也尝试按照web 所说的(步骤4)来获取用户信息,答案是:
curl --request GET https://account-d.docusign.com/oauth/userinfo--header "Authorization: Bearer eyJ0eXAiOiJNVCIsImFsZyI6IlJTMjU2Iiwia2lkIjoiNjgxODVmZjEtNGU1MS00Y2U5LWFmMWMtNjg5ODEyMjAzMzE3In0.AQoAAAABAAUABwAAYWSFlJrXSAgAAMko55ya10gCAP-ftnA70YROvfpqFSh7j7kVAAEAAAAYAAEAAAAFAAAADQAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwIgAkAAAAZjczYjYxMmMtOGI3Ny00YjRjLWFkZTQtZTI0ZWEyYjY4MTEwEgABAAAABgAAAGp3dF9iciMAJAAAAGY3M2I2MTJjLThiNzctNGI0Yy1hZGU0LWUyNGVhMmI2ODExMA.YHFoD2mQbwh8rdiPi8swg9kO9srlDyJcpqUo8XI5tdZki2I_Nla-qb9VaD4gAy8tSXVSY7unRjfClFDAqC8Ur73caHuZo7tN5tIKmXi6C3VzPWPGFJtsceKNEGMqwznw6OBVuPQG0IGlRjXK37Ur1nILLUWKb7w6O5Uz6y0e5uR8sxzZWh1adm2zHqd6khiQuAFB9vG2sS3jaudtck1qV6HRB_kARvUie1zglvHydc42Nc_o5GtIm3sGrqW7rio3YpHVX39nTKM-28kjOvPSNwzXp3IlZtaxuB6EdexrECH19nIaNbCe29LrdpzreRMyjEwwM309bOaKJ1KV82NbTQ"
# Response
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="https://account-d.docusign.com/">here</a>.</h2>
</body></html>
curl: (3) URL using bad/illegal format or missing URL
谢谢大家:)
【问题讨论】:
遇到同样的问题,你找到解决办法了吗? 【参考方案1】:只是查看代码,返回的是“acct”,一个字典。所以你需要使用account['account_id']
我找到了这个完整的例子:https://github.com/docusign/eg-01-python-jwt
在这里:https://github.com/docusign/eg-01-python-jwt/blob/master/example_base.py#L44
您会看到他们如何传递 account_id
希望这会有所帮助。祝你好运
【讨论】:
感谢您的回答,但问题是当我尝试获取account_id
时,端点"/oauth/userinfo"
失败。回复是"error":"internal_server_error","reference_id":"f20e360c-185d-463e-9f0b-ce95f38fe711"
【参考方案2】:
您必须使用request_jwt_user_token
而不是request_jwt_application_token
查看代码示例:https://github.com/docusign/eg-01-python-jwt/blob/master/example_base.py#L34
request_jwt_application_token
仅适用于部分 DocuSign 组织 API。
添加
来自评论: 我已更改对 request_jwt_user_token 的调用,并获得了另一个令牌,但它仍然失败。响应为 "error":"internal_server_error","reference_id":"846114d0-1bcd-47a6-ba23-317049b54d00"
答案:
您正在调用 /oauth/userinfo API 方法。但是没有包含 Authorization 标头。
一种方法是明确设置授权:
client.set_default_header("Authorization", "Bearer " + ds_access_token)
在您的情况下,SDK 应该为您设置它。可能是您使用了新的 client
对象、旧的 SDK 版本或其他问题。
我刚刚下载了eg-01-python-jwt code example repo,它运行良好。我建议您先下载示例应用程序并运行它,然后根据您的需要更新应用程序。
另外,检查您使用的 Python SDK 的版本:
pip3 show docusign_esign
Name: docusign-esign
Version: 3.0.0
Summary: DocuSign REST API
...
Location: /usr/local/lib/python3.7/site-packages
...
【讨论】:
我已经更改了对 request_jwt_user_token 的调用并且我得到了另一个令牌,但它仍然失败。回复是"error":"internal_server_error","reference_id":"846114d0-1bcd-47a6-ba23-317049b54d00"
【参考方案3】:
这个错误也可能是因为使用了过期的token(使用刷新端点来获取一个新的)
【讨论】:
以上是关于在 Python 中的 DocuSign 中获取令牌的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 DocuSign Python 代码生成 jwt 令牌