我们如何使用boto通过AWS AppSync发布GraphQL请求?
最终,我正在尝试模仿一个移动应用程序,但该应用程序使用python访问AWS上的无堆栈/云信息堆栈。不是javascript或放大。
主要的痛点是身份验证;我已经尝试了十二种不同的方法。这是当前的消息,它生成一个带有“ UnauthorizedException”和“权限被拒绝”的“ 401”响应,考虑到我收到的其他一些消息,这实际上是相当不错的。我现在正在使用“ aws_requests_auth”库来执行签名部分。我假设它使用本地环境中存储的/.aws/credentials
对我进行身份验证,还是对?
我对认知身份和集合将进入何处以及如何进入感到困惑。例如:说我想模仿注册顺序?
无论如何,代码看起来非常简单;我只是不验证身份。
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
APPSYNC_API_KEY = 'inAppsyncSettings'
APPSYNC_API_ENDPOINT_URL = 'https://aaaaaaaaaaaavzbke.appsync-api.ap-southeast-2.amazonaws.com/graphql'
headers = {
'Content-Type': "application/graphql",
'x-api-key': APPSYNC_API_KEY,
'cache-control': "no-cache",
}
query = """{
GetUserSettingsByEmail(email: "john@washere"){
items {name, identity_id, invite_code}
}
}"""
def test_stuff():
# Use the library to generate auth headers.
auth = BotoAWSRequestsAuth(
aws_host='aaaaaaaaaaaavzbke.appsync-api.ap-southeast-2.amazonaws.com',
aws_region='ap-southeast-2',
aws_service='appsync')
# Create an http graphql request.
response = requests.post(
APPSYNC_API_ENDPOINT_URL,
json={'query': query},
auth=auth,
headers=headers)
print(response)
# this didn't work:
# response = requests.post(APPSYNC_API_ENDPOINT_URL, data=json.dumps({'query': query}), auth=auth, headers=headers)
收益率
{
"errors" : [ {
"errorType" : "UnauthorizedException",
"message" : "Permission denied"
} ]
}
非常简单-一旦知道。有些事情我不喜欢:
我承担过IAM身份验证appsync有多种方法来处理身份验证。我们正在使用IAM,所以这就是我需要处理的,您的可能会有所不同。
Boto没有加入。我们希望像任何常规下注者一样发出请求,他们不使用boto,我们也不这样做。拖曳AWS Boto文档是浪费时间。
使用AWS4Auth库我们将向aws发送regular http请求,因此尽管我们可以使用python requests python,但它们需要通过附加标头进行身份验证。而且,当然,AWS auth标头是特殊的,并且与所有其他标头不同。You can try to work out how to do it yourself,或者您可以寻找已经做过的其他人:Aws_requests_auth,我刚开始使用的那个,可能效果很好,但我最终得到了AWS4Auth。还有许多其他价值可疑的东西。没有得到亚马逊认可或提供的(我可以找到)。
将appsync
指定为“服务”我们在叫什么服务?我在任何地方都没有找到任何这样做的例子。所有示例都是琐碎的S3或EC2甚至是EB,这些都留下了不确定性。我们应该和api网关服务通话吗?此外,您将此详细信息输入到AWS4Auth例程中或身份验证数据。显然,事后看来,该请求已到达Appsync,因此它将由Appsync进行身份验证,因此在将auth标头放在一起时,将“ appsync”指定为service。
它合在一起为:
import requests
from requests_aws4auth import AWS4Auth
# Use AWS4Auth to sign a requests session
session = requests.Session()
session.auth = AWS4Auth(
# An AWS 'ACCESS KEY' associated with an IAM user.
'AKxxxxxxxxxxxxxxx2A',
# The 'secret' that goes with the above access key.
'kwWxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgEm',
# The region you want to access.
'ap-southeast-2',
# The service you want to access.
'appsync'
)
# As found in AWS Appsync under Settings for your endpoint.
APPSYNC_API_ENDPOINT_URL = 'https://nqxxxxxxxxxxxxxxxxxxxke'
'.appsync-api.ap-southeast-2.amazonaws.com/graphql'
# Use JSON format string for the query. It does not need reformatting.
query = """
query foo {
GetUserSettings (
identity_id: "ap-southeast-2:8xxxxxxb-7xx4-4xx4-8xx0-exxxxxxx2"
){
user_name, email, whatever
}}"""
# Now we can simply post the request...
response = session.request(
url=APPSYNC_API_ENDPOINT_URL,
method='POST',
json={'query': query}
)
print(response.text)
哪个产量
# Your answer comes as a JSON formatted string in the text attribute, under data.
{"data":{"GetUserSettings":{"user_name":"0xxxxxxx3-9102-42f0-9874-1xxxxx7dxxx5"}}}
要摆脱硬编码的密钥/秘密,您可以使用本地AWS ~/.aws/config
和~/.aws/credentials
,并且可以通过这种方式完成...
credentials = boto3.session.Session().get_credentials()
...
credentials.access_key,
credentials.secret_key,
credentials.token
boto3.session.Session().region_name
这似乎确实尊重环境变量AWS_PROFILE
承担不同的角色。
请注意,STS.get_session_token不是这样做的方法,因为它可能会尝试从某个角色中扮演一个角色,具体取决于它与AWS_PROFILE值匹配的关键字。 credentials
文件中的标签将起作用,因为键就在那里,但是config
文件中的名称不起作用,因为这已经假定了角色。