Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Hi, thanks for the library! I'm attempting to use the API component in my react app to connect to an API gateway lambda API service using a custom domain name:
async getData() {
let apiName = 'media';
let path = '/';
let myInit = {
response: true
};
return await API.get(apiName, path, myInit);
}
componentDidMount() {
this.getData().then(response => {
this.setState({
data: response.json,
});
}).catch(error => {
console.log(error)
});
}
this results in:
Failed to load https://$MY_DOMAIN: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401.
Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
CORS is enabled on the API. I tried both setting
cors: true
in zappa settings, as well as using the AWS console to manually set CORS for the API.
As far as I can tell, Auth is configured correctly as the rest of the auth UI works fine.
Amplify.configure({
Auth: {
// REQUIRED - Amazon Cognito Identity Pool ID
identityPoolId: process.env.REACT_APP_identityPoolId,
// REQUIRED - Amazon Cognito Region
region: process.env.REACT_APP_region,
// OPTIONAL - Amazon Cognito User Pool ID
userPoolId: process.env.REACT_APP_userPoolId,
// OPTIONAL - Amazon Cognito Web Client ID (26-char alphanumeric string)
userPoolWebClientId: process.env.REACT_APP_userPoolWebClientId,
// OPTIONAL - Enforce user authentication prior to accessing AWS resources or not
mandatorySignIn: false,
// OPTIONAL - Configuration for cookie storage
cookieStorage: {
// REQUIRED - Cookie domain (only required if cookieStorage is provided)
domain: '.$APP_DOMAIN',
// OPTIONAL - Cookie path
path: '/',
// OPTIONAL - Cookie expiration in days
expires: 30,
// OPTIONAL - Cookie secure flag
secure: true
}
},
API: {
endpoints: [
{
name: "media",
endpoint: "https://$MY_DOMAIN",
region: 'ap-southeast-2',
service: 'lambda'
},
]
}
});
The IAM AuthRole for Cognito:
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*",
"cognito-identity:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"*"
]
}
]
}
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than AWS Amplify.
What is the expected behavior?
The API returns a 200 response.
I can see the auth headers (e.g. X-Amz-Security-Token) in the request, I assume I don't need to add additional jwt headers in the request.... I feel like I'm missing something obvious, but for the life of me can't figure it out (javascript noob). Thanks in advance.
Which versions of Amplify, and which browser / OS are affected by this issue? Did this work in previous versions?
amplify version 0.3.3
npm version 6.0.1
react version 16.3.2
You can turn on the debug mode to provide more info for us by setting window.LOG_LEVEL = 'DEBUG'; in your app.
@L226 In addition to setting cors on the API you also need to make sure that your API returns the CORS headers. If you're using lambda proxy integration it will look something like:
return {
body: JSON.stringify(YOUR-API-RESPONSE),
headers: {
"Access-Control-Allow-Credentials" : true,
"Access-Control-Allow-Origin": "*",
// PUT MORE HEADERS HERE
},
statusCode: 200,
};
Without those headers you get the message you're reporting.
Hi @L226 if you are invoking api gateway you don't need this service: 'lambda' parameter on Amplify configuration because you are invoking API gateway directly. You only need specify name and endpoint
Thanks for the replies.
Yeah I added those headers and the "Failed to load https://$MY_DOMAIN: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401." error has gone away.
I'm still getting a 401 response however:
Error: Request failed with status code 401
at createError (createError.js:16)
at settle (settle.js:18)
at XMLHttpRequest.handleLoad (xhr.js:77)
I believe this is due to my backend not handling the authorization correctly (python Flask + zappa). I will investigate further and update this ticket accordingly.
My investigations yielded nothing re. authorization in my backend itself. Zappa should just handle it automatically with my configuration.
Perhaps either my Cognito user pool or identity pool hasn't been configured correctly. I followed the documentation here. But I get these responses before sign-in:
POST https://cognito-identity.ap-southeast-2.amazonaws.com/ 400 (Bad Request)
and
x-amzn-ErrorMessage: Access to Identity 'ap-southeast-2:67fc67c1-921a-4484-8aac-198013eafd64' is forbidden.
After sign-in:
Error: Request failed with status code 401
at createError (createError.js:16)
at settle (settle.js:18)
at XMLHttpRequest.handleLoad (xhr.js:77)
from the API.get method, and the cognito login:
Request URL: https://cognito-idp.ap-southeast-2.amazonaws.com/
Request Method: POST
Status Code: 200 OK
Remote Address: 13.55.234.51:443
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: x-amzn-RequestId,x-amzn-ErrorType,x-amzn-ErrorMessage,Date
Connection: keep-alive
Content-Length: 35
Content-Type: application/x-amz-json-1.1
Date: Sat, 12 May 2018 09:55:21 GMT
x-amzn-RequestId: 95c9e049-55ca-11e8-87b8-2f573fb8980e
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
Content-Length: 1869
Content-Type: application/x-amz-json-1.1
DNT: 1
Host: cognito-idp.ap-southeast-2.amazonaws.com
Origin: http://localhost:3000
Referer: http://localhost:3000/
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
X-Amz-Target: AWSCognitoIdentityProviderService.ConfirmDevice
X-Amz-User-Agent: aws-amplify/0.1.x js
{DeviceKey: "ap-southeast-2_***********",鈥
AccessToken
:
"***********"
DeviceKey
:
"ap-southeast-2_***********"
DeviceName
:
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
DeviceSecretVerifierConfig
:
{Salt: "***********",鈥
PasswordVerifier
:
"***********"
Salt
:
"***********"
Which I guess means the sign in worked.
I also attempted to log the current session after sign in just to have a look:
Auth.currentSession().then(creds => {
console.log(creds.getIdToken().getJwtToken());
}).catch(err => {console.log('unable to get token:', err)})
but I just get
unable to get token: No current user
Cognito config:
Do the responses I'm getting mean that somewhere the auth flow is broken and/or I've borked my Cognito config? Sorry for the noob questions, first time Cognito user. Thanks
@L226 can you paste a code snippet of your sign-in call?
You should do something like this https://aws.github.io/aws-amplify/media/authentication_guide#sign-up
I'm using the withAuthenticator HOC on the App component. EDIT - Auth.currentCredentials() actually returns a valid CognitoIdentityCredentials object. Auth.currentSession() does not.
Ok, I found it. My API gateway was configured to use COGNITO_USER_POOLS as the authorizer, however it actually needed to be set to IAM_AUTH to utilise the AWS v4 signing used in Amplify. Thanks for your help!
Ok, I found it. My API gateway was configured to use COGNITO_USER_POOLS as the authorizer, however it actually needed to be set to IAM_AUTH to utilise the AWS v4 signing used in Amplify. Thanks for your help!
Hey @L226 I am using Cognito with a manual config on Amplify, and I'm getting that nasty CORS issue despite following your steps as well...
You mentioned that your authorizer was configured for Cognito, isn't it supposed to be configured like that in my case if I'm using Cognito with Amplify?
@waldothedeveloper need to set the Authorization header when calling API, as part of Amplify.configire -
Amplify.configure({
API: {
endpoints: [
{
name: "my-api",
endpoint: "https://XXXXXXXXX.execute-api.eu-west-1.amazonaws.com",
custom_header: async () => {
return { Authorization: `Bearer ${(await Auth.currentSession()).getIdToken().getJwtToken()}` };
}
}
]
}
});
https://docs.amplify.aws/lib/restapi/authz/q/platform/js#request-headers