使用 AWS Amplify & Cognito 调用 API 时安全令牌无效
Security token is invalid when calling API using AWS Amplify & Cognito
我正在尝试在现有 angular 项目中安装 AWS Amplify。我将 Cognito 用户池与 Cognito 联合身份一起使用。我可以登录,但是当我尝试调用 API 时,我收到消息 {"message":"The security token included in the request is invalid."}
,状态代码为 403 Forbidden。
我的 API 部署在 API 网关上,使用无服务器框架和此设置。我启用了 cors 并将授权方设置为 aws_iam.
// serverless.yml
frameworkVersion: ">=1.28.0 <2.0.0"
provider:
name: aws
runtime: go1.x
// --- omitted
functions:
get_devices:
handler: bin/get_devices
events:
- http:
path: devices
method: get
cors: true
authorizer: aws_iam
Amplify在文件中配置main.ts
// main.ts
const { userPoolId, identityPoolId, userPoolWebClientId, endpoint } = environment;
Amplify.configure({
Auth: {
region: 'us-east-1',
identityPoolId,
userPoolId,
userPoolWebClientId
},
API: {
endpoints: [
{
name: 'API',
endpoint,
},
]
}
});
我使用以下代码调用我的 API
@Injectable()
export class DevicesService {
private api: APIClass;
constructor(private http: HttpClient,
private httpUtils: HttpUtilsService) {
this.api = API;
}
findDevices(queryParams: QueryParamsModel): Observable<QueryResultsModel> {
const promise = this.api.get('myAPI', '/devices', {});
return from(promise).pipe(
map((devices) => {
console.log(devices);
return devices;
})
);
}
}
我有以下要求headers
Host: id.execute-api.us-east-1.amazonaws.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json, text/plain
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:4200/dashboard/(devices)
x-amz-date: 20190410T171055Z
Authorization: AWS4-HMAC-SHA256 Credential=undefined/20190410/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=920b1f832c6dfessssss8c3a0a0783848740dde68eaec95d3b35935
Origin: http://localhost:4200
以及以下响应headers
HTTP/2.0 403 Forbidden
content-type: application/json
content-length: 68
date: Wed, 10 Apr 2019 17:10:56 GMT
x-amzn-requestid: 9ab88ba9-5bb3-11e9-8467-e798767662220e
x-amzn-errortype: UnrecognizedClientException
x-amz-apigw-id: 67768JJDGGUYZ_SQ=
x-cache: Error from cloudfront
via: 1.1 5721f7035c3fc934bd3f96dbb04ba1e5.cloudfront.net (CloudFront)
x-amz-cf-id: hFy34Mv1OJBJF47UCT3wg0APyGYl0I4tgqw-K2ZeA==
X-Firefox-Spdy: h2
我希望有人能够帮助我。谢谢。
经过几天的搜索,我终于找到了解决这个问题的方法。
第一步是将 amplify 的日志级别设置为至少 DEBUG,这样您就可以看到发生了什么。
问题是由于以下问题,Amplify 在调用 API 时无法获取保存在本地存储中的凭据。
[DEBUG] 48:49.870 AuthClass - getting session failed TypeError: Cannot read property 'Stream' of undefined
at Object.computeSha256 (util.js:705)
at Request.COMPUTE_SHA256 (event_listeners.js:142)
at Request.callListeners (sequential_executor.js:105)
at Request.emit (sequential_executor.js:81)
at Request.emit (request.js:683)
at Request.transition (request.js:22)
at AcceptorStateMachine.runTo (state_machine.js:14)
at state_machine.js:26
at Request.<anonymous> (request.js:38)
at Request.<anonymous> (request.js:685)
在这种情况下,Amplify 只需调用 API 而无需任何签名,因此 403 Forbidden
.
的原因
解决方案是将 polyfill 放入 window
,而不是 polyfill.ts
,而是 index.html
,如下所示:
<script>
if (global === undefined) {
var global = window;
}
// If you need debug message from amplify
window['LOG_LEVEL'] = 'DEBUG';
</script>
终于可以用了。
我正在尝试在现有 angular 项目中安装 AWS Amplify。我将 Cognito 用户池与 Cognito 联合身份一起使用。我可以登录,但是当我尝试调用 API 时,我收到消息 {"message":"The security token included in the request is invalid."}
,状态代码为 403 Forbidden。
我的 API 部署在 API 网关上,使用无服务器框架和此设置。我启用了 cors 并将授权方设置为 aws_iam.
// serverless.yml
frameworkVersion: ">=1.28.0 <2.0.0"
provider:
name: aws
runtime: go1.x
// --- omitted
functions:
get_devices:
handler: bin/get_devices
events:
- http:
path: devices
method: get
cors: true
authorizer: aws_iam
Amplify在文件中配置main.ts
// main.ts
const { userPoolId, identityPoolId, userPoolWebClientId, endpoint } = environment;
Amplify.configure({
Auth: {
region: 'us-east-1',
identityPoolId,
userPoolId,
userPoolWebClientId
},
API: {
endpoints: [
{
name: 'API',
endpoint,
},
]
}
});
我使用以下代码调用我的 API
@Injectable()
export class DevicesService {
private api: APIClass;
constructor(private http: HttpClient,
private httpUtils: HttpUtilsService) {
this.api = API;
}
findDevices(queryParams: QueryParamsModel): Observable<QueryResultsModel> {
const promise = this.api.get('myAPI', '/devices', {});
return from(promise).pipe(
map((devices) => {
console.log(devices);
return devices;
})
);
}
}
我有以下要求headers
Host: id.execute-api.us-east-1.amazonaws.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: application/json, text/plain
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:4200/dashboard/(devices)
x-amz-date: 20190410T171055Z
Authorization: AWS4-HMAC-SHA256 Credential=undefined/20190410/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=920b1f832c6dfessssss8c3a0a0783848740dde68eaec95d3b35935
Origin: http://localhost:4200
以及以下响应headers
HTTP/2.0 403 Forbidden
content-type: application/json
content-length: 68
date: Wed, 10 Apr 2019 17:10:56 GMT
x-amzn-requestid: 9ab88ba9-5bb3-11e9-8467-e798767662220e
x-amzn-errortype: UnrecognizedClientException
x-amz-apigw-id: 67768JJDGGUYZ_SQ=
x-cache: Error from cloudfront
via: 1.1 5721f7035c3fc934bd3f96dbb04ba1e5.cloudfront.net (CloudFront)
x-amz-cf-id: hFy34Mv1OJBJF47UCT3wg0APyGYl0I4tgqw-K2ZeA==
X-Firefox-Spdy: h2
我希望有人能够帮助我。谢谢。
经过几天的搜索,我终于找到了解决这个问题的方法。
第一步是将 amplify 的日志级别设置为至少 DEBUG,这样您就可以看到发生了什么。
问题是由于以下问题,Amplify 在调用 API 时无法获取保存在本地存储中的凭据。
[DEBUG] 48:49.870 AuthClass - getting session failed TypeError: Cannot read property 'Stream' of undefined
at Object.computeSha256 (util.js:705)
at Request.COMPUTE_SHA256 (event_listeners.js:142)
at Request.callListeners (sequential_executor.js:105)
at Request.emit (sequential_executor.js:81)
at Request.emit (request.js:683)
at Request.transition (request.js:22)
at AcceptorStateMachine.runTo (state_machine.js:14)
at state_machine.js:26
at Request.<anonymous> (request.js:38)
at Request.<anonymous> (request.js:685)
在这种情况下,Amplify 只需调用 API 而无需任何签名,因此 403 Forbidden
.
解决方案是将 polyfill 放入 window
,而不是 polyfill.ts
,而是 index.html
,如下所示:
<script>
if (global === undefined) {
var global = window;
}
// If you need debug message from amplify
window['LOG_LEVEL'] = 'DEBUG';
</script>
终于可以用了。