如何在我的iOS / Swift项目中调用我的AWS API Gateway REST API

时间:2019-02-10 15:45:54

标签: ios swift amazon-web-services aws-api-gateway aws-amplify

我创建了一个单一视图应用程序in Xcode,然后按照AWS Amplify iOS SDK指南使用现有的Cognito用户池插入身份验证。做工精美。

然后,使用AWS Amplify,我added a REST API允许我的iOS应用通过Amplify生成的API网关和Lambda函数访问预先存在的DynamoDB表。但是,我必须重新连接所有东西,才能使用我之前存在的Cognito用户池,因为Amplify CLI意外地创建了一个新用户池,该用户池链接到它创建的REST API。

尝试调用我的API时出现以下错误,无论我做什么我都无法使它消失:

Optional("{\"message\":\"Authorization header requires \'Credential\' parameter. 
Authorization header requires \'Signature\' parameter. Authorization header requires 
\'SignedHeaders\' parameter. 
Authorization=abJarWQiOiJyR0NiTHFsbVwvbWdGeXgzcVA1YmNRaV...
403

更新5 有关更多血腥细节,请参阅我的Amplify AWS iOS SDK issue。 :)

更新4 此更新优先于我之前的更新,因为如上面的错误所示,现在似乎很清楚,我没有通过我的iOS应用程序的经过身份验证的Cognito用户正确调用REST API。我注意到Amplify用两个 App客户端创建了一个用户池,一个用于Web访问,一个用于移动访问。我先前存在的用户池只有一个针对Web访问量身定制的App Client。因此,我创建了一个新的带有移动客户端访问权限的App Client。

不幸的是,我得到了相同的确切错误。所以我想知道是否需要重新接线?也许我有令牌问题。正如我在下面的注释中提到的那样,也许我不应该使用REST API指南中指定的OIDC令牌?也许我应该使用AWS Credentials END UPDATE 4

我的API有一个资源/items,而我有一个ANY和一个OPTIONS方法。 ANY方法没有为方法请求指定的任何URL查询字符串参数。但是它确实为请求正文指定了RequestSchema类型的application/json

我的API调用功能完全是specified in the AWS Amplify iOS SDK for the REST API(我按照他们的指示使用Cognito用户池授权者调用API网关端点),只是我将httpMethodNamePOST更改为{ {1}},因为POST导致崩溃。看起来是这样的:

GET

上面给出的错误由该func doInvokeAPI(token:String) { // change the method name, or path or the query string parameters here as desired let httpMethodName = "GET" // the guid is the partition key for the DynamoDB table let URLString = "/items/178dc797-4e3d-5bc4-815f-a280536fcd3a" //let queryStringParameters = ["key1":"{value1}"] let headerParameters = [ "Content-Type": "application/json", "Accept": "application/json", "Authorization": token ] //let httpBody = "{ \n " + // "\"key1\":\"value1\", \n " + // "\"key2\":\"value2\", \n " + // "\"key3\":\"value3\"\n}" // Construct the request object let apiRequest = AWSAPIGatewayRequest(httpMethod: httpMethodName, urlString: URLString, queryParameters: nil, headerParameters: headerParameters, httpBody: nil) ... ... invocationClient.invoke(apiRequest).continueWith { (task: AWSTask) -> Any? in if let error = task.error { print("Error occurred: \(error)") // Handle error here return nil } // Handle successful result here let result = task.result! let responseString = String(data: result.responseData!, encoding: .utf8) print(responseString as Any) print(result.statusCode) return nil } } 打印。

我的DynamoDB表应该是:print(responseString)分区键。引导字符串。

我很确定我要传递的所有API都是一个userId,以便API可以检索与其关联的所有项目。不需要我的排序键。

我如何通过API Gateway REST API发出此GET请求有问题吗?

更新1 与我的Lambda函数关联的JavaScript文件有两个:userIdindex.js,由Amplify创建。

app.js很短:

index.js

const awsServerlessExpress = require('aws-serverless-express'); const app = require('./app'); const server = awsServerlessExpress.createServer(app); exports.handler = (event, context) => { console.log(`EVENT: ${JSON.stringify(event)}`); awsServerlessExpress.proxy(server, event, context); }; 包含一些设置(第一个屏幕快照),然后是app.jsgetputpost的一系列方法。我只是为delete方法提供了两个屏幕截图-这个问题的主题。)

enter image description here

enter image description here

enter image description here

更新2 这是单击API的get方法的“集成请求”时看到的。请注意,我没有映射模板的下拉菜单。

enter image description here

更新3 但是我确实有Amplify创建的ANY阶段。但是我仍然看不到任何地方的映射模板。

enter image description here

1 个答案:

答案 0 :(得分:-1)

"/items/{userId}"只是一个字符串。尝试"/items/\(userId)"

对不起,我的积分不足以发表评论。