sst / guide

Repo for guide.sst.dev
https://guide.sst.dev
MIT License
3.68k stars 444 forks source link

Comments: Test the APIs #112

Closed jayair closed 6 years ago

jayair commented 7 years ago

Link to chapter - http://serverless-stack.com/chapters/test-the-apis.html

jayair commented 6 years ago

@lucasgonze Thanks for reporting back. It can be a tricky issue to track down.

lucasgonze commented 6 years ago

Moving my code to a non-ChromeOS machine did fix the EACCESS problem.

After running serverless deploy for the first time. I got the same "CognitoIdentityCredentials is not authorized to perform: execute-api" error as @Jonarod, and solved it the same way, by creating a new Federated Identity Pool. The reason why this desparate measure works is that you can then edit the policy document, which has a hard coded reference to the gateway returned by serverless deploy.

I couldn't find another way to edit the policy document once it has been created, though I'm sure one exists.

After this I got 200 OK on my apig test.

johnnybigert commented 6 years ago

Thank you for a superb guide!

Regarding @Spartano's comment from above. I am using Git Bash on Windows 10 and was getting the following:

 $ apig-test
    --username admin@example.com
    --password Passw0rd!
    --user-pool-id us-east-1_VxxxM
    --app-client-id 4xxxd
    --cognito-region us-east-1
    --identity-pool-id us-east-1:fxxx1
    --invoke-url https://9xxxf.execute-api.us-east-1.amazonaws.com/prod        <<<<<<<<
    --api-gateway-region us-east-1
    --path-template /notes                                                     <<<<<<<<
    --method POST
    --body "{\"content\":\"hello world\",\"attachment\":\"hello.jpg\"}"
 Authenticating with User Pool
 Getting temporary credentials
 Making API request
 { status: 403,
   statusText: 'Forbidden',
   data: { message: 'Forbidden' } }

By moving the slash from --path-template to --invoke-url it started working:

 $ apig-test
    --username admin@example.com
    --password Passw0rd!
    --user-pool-id us-east-1_VxxxM
    --app-client-id 4jxxxld
    --cognito-region us-east-1
    --identity-pool-id us-east-1:fdxxxb1
    --invoke-url https://9xxxf.execute-api.us-east-1.amazonaws.com/prod/       <<<<<<<<
    --api-gateway-region us-east-1
    --path-template notes                                                      <<<<<<<<
    --method POST
    --body "{\"content\":\"hello world\",\"attachment\":\"hello.jpg\"}"
 Authenticating with User Pool
 Getting temporary credentials
 Making API request
 { status: 200,
   statusText: 'OK',
   data:
    { userId: 'us-east-1:4xxx3',
      noteId: 'exxxf',
      content: 'hello world',
      attachment: 'hello.jpg',
      createdAt: 1511260183884 } }

Created a pull request and added this tip to the 403 troubleshooting section.

jayair commented 6 years ago

@johnnybigert Thank you for this.

fpoumian commented 6 years ago

I'm getting the following response after issuing the initial apig-test command:

Authenticating with User Pool
Unexpected key 'UserContextData' found in params

Any idea what this might be?

jayair commented 6 years ago

@fpoumian Can I see the full command that you are using?

svj13 commented 6 years ago

Does anyone know where I may be going wrong? It says tthe JSON object, but earlier when I had the JSON arg wrong, it errored out before it authenticated with the user pool etc

This is my input apig-test --username admin@example.com --password Passw0rd! --user-pool-id us-east-2_xxxxC --app-client-id 7xxxe --cognito-region us-east-2 --identity-pool-id us-east-2:7xxxxb --invoke-url https://dnxxxxd.execute-api.us-east-2.amazonaws.com/prod --api-gateway-region us-east-2 --path-template /notes --method POST --body "{\"content\":\"hello world\",\"attachment\":\"hello.jpg\"}"

This is the output I get image

lucasgonze commented 6 years ago

@svj13 There's an issue in your escaping of the --body argument. Replace the outer double quotes with singles.

svj13 commented 6 years ago

@lucasgonze replacing with single quotes, removing/adding escape characters etc all come up with the same error

I could copy up all of the inputs I've tried to see if anything can be spotted that I'm doing wrong

lucasgonze commented 6 years ago

Can you modify index.js:160 to log what it's trying to parse?

svj13 commented 6 years ago

@lucasgonze image

davidcharlesweber commented 6 years ago

Fellow 403 errors, check your IAM policy for Auth users.

I had included an accidental space and was getting the 403 Cognito_notesidentitypoolAuth_Role/CognitoIdentityCredentials is not authorized to perform: execute-api:Invoke

evangow commented 6 years ago

Have you considered using making aws-api-gateway-cli-test a local dev dependency and then invoking the local package using 'npx'? For people who are hesitant to install packages globally, this would be a nice tweak to the tutorial

zwik commented 6 years ago

I only figured this one out now, i'm having difficulties with our proxy but already created a new ticket for it: https://github.com/AnomalyInnovations/serverless-stack-com/issues/175

d0ruk commented 6 years ago

In case this might help somebody;

const userDetails = {
  USERNAME: "test",
  PASSWORD: "password",
};
const args = [
  "--username", userDetails["USERNAME"],
  "--password", userDetails["PASSWORD"],
  "--user-pool-id", output.UserPool,
  "--app-client-id", output.UserPoolClient,
  "--cognito-region", output.Region,
  "--identity-pool-id", output.IdentityPool,
  "--invoke-url", output.ServiceEndpoint,
  "--api-gateway-region", output.Region,
  "--path-template", "/notes",
  "--method", "POST",
  "--body", "{\"content\":\"hello world\",\"attachment\":\"hello.jpg\"}"
];

spawn("./node_modules/.bin/apig-test", args).stdout.pipe(process.stdout);
jayair commented 6 years ago

@evangow Yeah that's a good idea. I'll take a look into it.

@d0ruk That looks interesting. What does this bit of code do?

d0ruk commented 6 years ago

@jayair repo

It maps the stack outputs to the apig-test CLI.

JackEdwardLyons commented 6 years ago

How do I copy this into my terminal... everytime I copy and paste my code in, it just adds a > for each new line... I can never run the code :( It looks like this no matter what I do and then when I try to clear the console it just adds another > and a new line... how do i escape this? Here's my code:

apig-test\ 
--username='admin@example.com'\
--password='Passw0rd!'\
--user-pool-id='us-east-2_AxxxxfBnL'\
--app-client-id='4vt88xxxxxxvv6cubd'\
--cognito-region='us-east-2'\ 
--identity-pool-id='us-east-2:3d8xxxxxxxe9982253f'\
--invoke-url='https://akse8rq9w0.execute-api.us-east-2.amazonaws.com/prod'\
--api-gateway-region='us-east-2'\
--path-template='/notes'\
--method='POST'\
--body='{"content":"hello world","attachment":"hello.jpg"}'\

If i then go in and delete all the > I also get this error: Invalid UserPoolId format.

jayair commented 6 years ago

@JackEdwardLyons Are you on OS X or Windows?

JackEdwardLyons commented 6 years ago

i'm on Mac OS X -- sorry I should have mentioned that above. Here's the code I am running, which does actually run now, but I get an error saying incorrect username or password even though they are exactly the same as the example in the earlier chapter:

apig-test      --username=admin@example.com   --password=Passw0rd!    --user-pool-id=us-east-2_akse8rq9w0    --app-client-id=4vt88hu5be99xxxxxx6cubd    --cognito-region=us-east-2    --identity-pool-id=us-east-2:3d82638c-ba44-43xxxxe-40ae9982253f    --invoke-url=https://akse8rq9w0.execute-api.us-east-2.amazonaws.com/prod    --api-gateway-region=us-east-2    --path-template=/notes    --method=POST    --body='{"content":"hello world","attachment":"hello.jpg"}'
jefaramvangorp commented 6 years ago

Hi, I am also getting the 502 error, but none of the above solutions proved helpful.

I think it has something to do with how the code is transpiled, because I can see the following error in cloudwatch:

Syntax error in module 'list': SyntaxError
async function main(event, context, callback) {
^^^^^^^^
SyntaxError: Unexpected token function
at createScript (vm.js:56:10)
at Object.runInThisContext (vm.js:97:10)
at Module._compile (module.js:542:28)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)

I got this error before when I was testing the api calls locally with serverless. It turned out I was using an older version of node and upgrading to 8.9.3 resolved that issue.

I am using the following versions of the tools:

serverless -v 1.17.0
node -v 8.9.3
npm -v 5.6.0

Could you please help me figure this out?

JackEdwardLyons commented 6 years ago

Ok I'm getting closer. I managed to add a config to iTerm2 to allow copy and pasting into the terminal and not running the command immediately > you can read the post here <

Now, I get an error Incorrect username or password even though I have created the user as listed in the earlier chapter.... Not sure what to do from here. I even created another user and confirmed / enabled it, but it still says Incorrect username or password

jayair commented 6 years ago

@JackEdwardLyons I'm not sure what is going on with iTerm2 in this case but for this chapter - https://serverless-stack.com/chapters/create-a-cognito-test-user.html; can you ensure that you are creating a user with the password correctly?

Instead of copying and pasting can you try typing in the command yourself to make sure that it is being created correctly?

jayair commented 6 years ago

@jefaramvangorp It seems like your code is not being transpiled properly. Can you check if you've completed this chapter - https://serverless-stack.com/chapters/add-support-for-es6-es7-javascript.html?

jefaramvangorp commented 6 years ago

@jayair Thanks for your response. I found my error while I was typing a reply to your question. I feel really dumb now, but it turned out that I had added the babel config file as babelrc instead of .babelrc (note the dot in the second name). Renaming the file fixed the issue.

topguncharl commented 6 years ago

I also got the "status: 403" when testing my API, however thanks to the great people working with "serverless-stack" I found my way to a solution (although it took some trial and error). To help others I paste my documented log of what I did to resolve the issue below.

My initial response -> Response ->

{ status: 403,
  statusText: 'Forbidden',
  data: 
   { Message: 'User: arn:aws:sts::477655596505:assumed-role/Cognito_cjnotesAuth_Role/CognitoIdentityCredentials is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:********6505:xxxxxxxxxx/prod/POST/notes' } }

My Log to resolution ->

Cognito Identity -> Role name -> cjnotes Authenticated role -> Cognito_cjnotesAuth_Role

Open IAM Policy simulator-> https://policysim.aws.amazon.com/home/index.jsp Click to select Roles (not Users) Selected role -> Cognito_cjnotesAuth_Role Service -> API Gateway Action -> Invoke Expand Amazon API Gateway row Paste API gateway endpoint -> arn:aws:execute-api:us-east-1:*:xxxxxxxxxx/* Click button Run Simulation Response i policy simulator ->

Amazon API Gateway
Invoke
execute-api-general
execute-api-general
**denied** 

NOW I HAVE VERIFIED PERMISSION IS NOT OK FOR MY ROLE (Authenticated role -> Cognito_cjnotesAuth_Role) I NEED TO FIX THIS -> In AWS console open IAM- > https://console.aws.amazon.com/iam/home?region=us-east-1#/roles Click on the role -> Cognito_cjnotesAuth_Role Expand policy row Click Edit policy Click tab JSON

Edit policy -> (bold is the changed stuff) ->

{
    "Version": "2012-10-17",
   "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*",
                "execute-api:Invoke"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:*:xxxxxxxxxx/*"
            ]
        }
 ]
}

(replace xxxxxxxxxx with your value)

Click Review Policy Click Save Changes

I RUN AGAIN In terminal ->

apig-test \
--username='admin@example.com' \
--password='Passw0rd!' \
--user-pool-id='us-east-1_xxxxxxxxx' \
--app-client-id='dmfq6no2nhqshakvfbueinos2' \
--cognito-region='us-east-1' \
--identity-pool-id='us-east-1:c8b8e333-9d52-4c41-9e91-xxxxxxxxxxxx' \
--invoke-url='https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod' \
--api-gateway-region='us-east-1' \
--path-template='/notes' \
--method='POST' \
--body='{"content":"hello world","attachment":"hello.jpg"}'

Response ->

{ status: 200,
  statusText: 'OK',
  data: 
   { userId: 'us-east-1:xxxxxxxx-0c52-402f-8f6f-09f163b08735',
     noteId: 'eb4d3f50-09bc-11e8-ab2c-b9edda96b9fd',
     content: 'hello world',
     attachment: 'hello.jpg',
     createdAt: 1517756764101 } }
jayair commented 6 years ago

@topguncharl Thank you very much for adding in detail your debug process. It will help a lot of other folks that are going to go through it. I formatted it a bit with some Markdown for clarity.

ivanms1 commented 6 years ago

@jayair Hello it's me again, sorry to bother you again. I am getting the following error now

Authenticating with User Pool
Getting temporary credentials
Making API request
{ status: 500,
  statusText: 'Internal Server Error',
  data: { status: false } }

I've tried to navigate through the comments having the same error, I went back to the 1.17.0 serverless version, and then I couldn't re-deploy because I got an error about updating Lambda. The CloudWatch logs don't say too much either.

jayair commented 6 years ago

@ivanms1 This is an error we generate in our Lambda. So you can add console.log in the Lambda to debug what is going on. The logs will show up in CloudWatch.

ivanms1 commented 6 years ago

@jayair by Lambda you mean the create, delete, etc functions?

jayair commented 6 years ago

@ivanms1 Yeah it is in those functions that we generate this error. For example, for the get case we generate it here - https://github.com/AnomalyInnovations/serverless-stack-demo-api/blob/master/get.js#L25

So you could add some debug messages before that line to see what is going on.

ivanms1 commented 6 years ago

@jayair I already have a console.log in all those functions, maybe I set up the CloudWatch wrong, I still get logs tho. I don't see an error message anywhere

(dd007ab9-12ca-11e8-b201-8fec456d096a) Verifying Usage Plan for request: dd007ab9-12ca-11e8-b201-8fec456d096a. API Key: API Stage: binkm6jb4m/prod
(dd007ab9-12ca-11e8-b201-8fec456d096a) API Key authorized because method 'POST /notes' does not require API Key. Request will not contribute to throttle or quota limits
(dd007ab9-12ca-11e8-b201-8fec456d096a) Usage Plan check succeeded for API Key and API Stage binkm6jb4m/prod
(dd007ab9-12ca-11e8-b201-8fec456d096a) Starting execution for request: dd007ab9-12ca-11e8-b201-8fec456d096a
(dd007ab9-12ca-11e8-b201-8fec456d096a) HTTP Method: POST, Resource Path: /notes
(dd007ab9-12ca-11e8-b201-8fec456d096a) Method request path:
{}
(dd007ab9-12ca-11e8-b201-8fec456d096a) Method request query string:
{}
(dd007ab9-12ca-11e8-b201-8fec456d096a) Method request headers: {Accept=application/json, x-amz-date=20180216T033833Z, CloudFront-Viewer-Country=TH, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, CloudFront-Is-Mobile-Viewer=false, User-Agent=axios/0.17.1, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=binkm6jb4m.execute-api.us-east-2.amazonaws.com, x-amz-security-token=AgoGb3JpZ2luEKP//////////wEaCXVzLWVhc3QtMiKAAlTmYUda+bA65tBI6dCcB4aubUmGzAvAvBeZubcXXl/z0PWg5aoZ/G6FrFlfWcgKy9XxiB8wKvVaZDVbdULvE6NF0LoLIIstPS5wlthyEk8VSM3oYAGfqvQvZ9NW/NM0VzKeegM2zi0bQg10Az9XBdDzYIMGeMSbnE41dZ/T7kcPvs1veqGpBxHYA5+PooAInky7VgotOCv9FAvXwLoRQqN4R51jYYEcI+SDyg1y42MmD12xdB5RAc4rzfCZ9zSwDnWlyAHXDqBCuNb0FXlXUs051IyjCUzRliG5rXHz+UZSgpRjQTPMmJVQl9wCIba3cwmg3bDfvKOCy9c++mLUvT8qrwUInf//////////ARAAGgw1MDMxNzk5Nzc2NzgiDLCgFaM9V4ntI9euVyqDBcC0PktYfMUGtWkItZAPiS3+VNZE2iZV2r3mG5sv6X9USewMpzN4Uu8E1M4Cy7mczVoZDdRx0a+CLph8kJjzk9m5HnavbKMtBgo1YbpG9Pd6+Rx9hWpLGapZ2DjIfwk+zTPAmn+1xbXyTsoFOG+xmmp7x1wBsjXv4byyXExSSvgmK78Z7R8IW4o5rGI6fd9zlq7mUM2ETJk [TRUNCATED]
(dd007ab9-12ca-11e8-b201-8fec456d096a) Method request body before transformations:
{
    "content": "hello world",
    "attachment": "hello.jpg"
}
(dd007ab9-12ca-11e8-b201-8fec456d096a) Endpoint request URI: https://lambda.us-east-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-2:503179977678:function:notes-app-api-prod-create/invocations
(dd007ab9-12ca-11e8-b201-8fec456d096a) Endpoint request headers: {x-amzn-lambda-integration-tag=dd007ab9-12ca-11e8-b201-8fec456d096a, Authorization=************************************************************************************************************************************************************************************************************************************************************************************************************************869208, X-Amz-Date=20180216T033833Z, x-amzn-apigateway-api-id=binkm6jb4m, X-Amz-Source-Arn=arn:aws:execute-api:us-east-2:503179977678:binkm6jb4m/prod/POST/notes, Accept=application/json, User-Agent=AmazonAPIGateway_binkm6jb4m, X-Amz-Security-Token=FQoDYXdzEJz//////////wEaDBGNrv8zmtc8+GkAuyK3A3BP+66txghNqIn+He/DVAwvbYw/WYdLoPR9/l02bBQvMGn6OpMwDReEnuq+A5W4iYxCH1Nx1+kG249YCZP1bgoDHEea+7oMluDiJoZxKepPXWNJlIKMSni2Mo2Yga0QjUX4kNdSB7BUz95TXTvX28UaA/KAW45wJqXhz1zGTV6zVCbIlT8GpeTrm/dekdRuAN3iSEfGEwGpIAuOFnCbHaadpRLjztedMKMGD8dQuVsj+H+pl1W+LmylbHlOG00md0r52lL3THGEoftMXX6lz5wNHag1gK3HyS9IBvUJYoGksNbxeJTNsvr [TRUNCATED]
(dd007ab9-12ca-11e8-b201-8fec456d096a) Endpoint request body after transformations: {"resource":"/notes","path":"/notes","httpMethod":"POST","headers":{"Accept":"application/json","CloudFront-Forwarded-Proto":"https","CloudFront-Is-Desktop-Viewer":"true","CloudFront-Is-Mobile-Viewer":"false","CloudFront-Is-SmartTV-Viewer":"false","CloudFront-Is-Tablet-Viewer":"false","CloudFront-Viewer-Country":"TH","Content-Type":"application/json","Host":"binkm6jb4m.execute-api.us-east-2.amazonaws.com","User-Agent":"axios/0.17.1","Via":"1.1 2578d443f39536d43a9a2eccaa197f91.cloudfront.net (CloudFront)","X-Amz-Cf-Id":"M7sRK9ayuIl-I-RT8FGqtHCPSxOLSuKooj1F8U-KhamS25DR6lra0A==","x-amz-date":"20180216T033833Z","x-amz-security-token":"AgoGb3JpZ2luEKP//////////wEaCXVzLWVhc3QtMiKAAlTmYUda+bA65tBI6dCcB4aubUmGzAvAvBeZubcXXl/z0PWg5aoZ/G6FrFlfWcgKy9XxiB8wKvVaZDVbdULvE6NF0LoLIIstPS5wlthyEk8VSM3oYAGfqvQvZ9NW/NM0VzKeegM2zi0bQg10Az9XBdDzYIMGeMSbnE41dZ/T7kcPvs1veqGpBxHYA5+PooAInky7VgotOCv9FAvXwLoRQqN4R51jYYEcI+SDyg1y42MmD12xdB5RAc4rzfCZ9zSwDnWlyAHXDqBCuNb0FXlXUs051IyjCUzRliG5rXHz [TRUNCATED]
(dd007ab9-12ca-11e8-b201-8fec456d096a) Sending request to https://lambda.us-east-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-2:503179977678:function:notes-app-api-prod-create/invocations
(dd007ab9-12ca-11e8-b201-8fec456d096a) Received response. Integration latency: 115 ms
(dd007ab9-12ca-11e8-b201-8fec456d096a) Endpoint response body before transformations:
{
    "statusCode": 500,
    "headers": {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": true
    },
    "body": "{\"status\":false}"
}
(dd007ab9-12ca-11e8-b201-8fec456d096a) Endpoint response headers: {X-Amz-Executed-Version=$LATEST, x-amzn-Remapped-Content-Length=0, Connection=keep-alive, x-amzn-RequestId=dd0499ca-12ca-11e8-b76e-b92f44150ead, Content-Length=132, Date=Fri, 16 Feb 2018 03:38:33 GMT, X-Amzn-Trace-Id=root=1-5a865239-7c7e925f212f79fb2c857beb;sampled=0, Content-Type=application/json}
(dd007ab9-12ca-11e8-b201-8fec456d096a) Method response body after transformations:
{
    "status": false
}
(dd007ab9-12ca-11e8-b201-8fec456d096a) Method response headers: {Access-Control-Allow-Origin=*, Access-Control-Allow-Credentials=true, X-Amzn-Trace-Id=sampled=0;root=1-5a865239-7c7e925f212f79fb2c857beb}
(dd007ab9-12ca-11e8-b201-8fec456d096a) Successfully completed execution
(dd007ab9-12ca-11e8-b201-8fec456d096a) Method completed with status: 500
jayair commented 6 years ago

@ivanms1 Are these the Lambda logs? You should be able to see your console.log if you followed the steps in this chapter - https://serverless-stack.com/chapters/api-gateway-and-lambda-logs.html

ivanms1 commented 6 years ago

@jayair ok I think I am finally getting somewhere here, after I realized I've been looking at the wrong logs. This is the error I a getting on my create function.

2018-02-19T06:12:58.561Z    ee074e14-153b-11e8-9638-d525c1b2a4e8    { ValidationException: One or more parameter values were invalid: Missing the key userId in the item
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:48:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
message: 'One or more parameter values were invalid: Missing the key userId in the item',
code: 'ValidationException',
time: 2018-02-19T06:12:58.559Z,
requestId: '3LLKC80485R47TOBCVUR20IISFVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 18.56955639307114 }

I checked my create.js I corrected one typo, but I am still getting the same error.

qazuor commented 6 years ago

Hi @jayair . I have the same problem that @ivanms1. API call test fail because userId is missing.

This is my API call test:

qazuor@NOSE4 /v/w/RevolAppBackend> apig-test \
                                   --username='MYEMAIL' \
                                   --password='MYPASS' \
                                   --user-pool-id='us-east-1_n6A0s2ESX' \
                                   --app-client-id='31n7jcfg8omah59vij29c6o0jr' \
                                   --cognito-region='us-east-1' \
                                   --identity-pool-id='us-east-1:c600aabf-ddf3-486d-a250-8bcfadde9779' \
                                   --invoke-url='https://btoih37hxb.execute-api.us-east-1.amazonaws.com/prod' \
                                   --api-gateway-region='us-east-1' \
                                   --path-template='/events' \
                                   --method='POST' \
                                   --body='{"content":"hello world","attachment":"hello.jpg"}'
Authenticating with User Pool
Getting temporary credentials
Making API request
{ status: 500,
  statusText: 'Internal Server Error',
  data: { status: false } }

I put a console logs in my function first to log the error:

2018-02-19 07:53:08.420 (-03:00)    119ce312-1563-11e8-9914-4d534293ef89    { ValidationException: One or more parameter values were invalid: Type mismatch for key userId expected: S actual: NULL
    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:48:27)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
  message: 'One or more parameter values were invalid: Type mismatch for key userId expected: S actual: NULL',
  code: 'ValidationException',
  time: 2018-02-19T10:53:08.417Z,
  requestId: 'TLFSSK6BAKV2MDU93008ROH2BFVV4KQNSO5AEMVJF66Q9ASUAAJG',
  statusCode: 400,
  retryable: false,
  retryDelay: 34.34380403084148 }

And the to see what info have in event.requestContext:

requestContext: {
    requestTime: '19/Feb/2018:10:38:42 +0000',
    path: '/prod/events',
    accountId: '751262903915',
    protocol: 'HTTP/1.1',
    resourceId: 'avzh5i',
    stage: 'prod',
    requestTimeEpoch: 1519036722589,
    requestId: '0e03050e-1561-11e8-a372-c1ed968bbe7b',
    identity: {
        cognitoIdentityPoolId: null,
        accountId: null,
        cognitoIdentityId: null,
        caller: null,
        sourceIp: '181.93.216.110',
        accessKey: null,
        cognitoAuthenticationType: null,
        cognitoAuthenticationProvider: null,
        userArn: null,
        userAgent: 'axios/0.17.1',
        user: null
    },
    resourcePath: '/events',
    httpMethod: 'POST',
    apiId: 'btoih37hxb'
}

All cognito related info, into event.requestContext.identity is empty.

I google it for hours but, I cant found any solution.

This is my serverless.yml file:

service: revolapp

# Use serverless-webpack plugin to transpile ES6/ES7
plugins:
  - serverless-webpack

# Enable auto-packing of external modules
custom:
  webpackIncludeModules: true

provider:
  name: aws
  runtime: nodejs6.10
  stage: prod
  region: us-east-1
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:us-east-1:*:*"

functions:
  create-event:
    handler: services/events/create.main
    events:
      - http: post /events
        cors: true
        authorizer: aws_iam

  get-event:
    handler: services/events/get.main
    events:
      - http: get /events/{id}
        cors: true
        authorizer: aws_iam

  update-event:
    handler: services/events/update.main
    events:
      - http: put /events/{id}
        cors: true
        authorizer: aws_iam

  delete-event:
    handler: services/events/delete.main
    events:
      - http: delete /events/{id}
        cors: true
        authorizer: aws_iam

  list-events:
    handler: services/events/list.main
    events:
      - http: get /events
        cors: true
        authorizer: aws_iam

This my create.js file:

import uuid from "uuid";

import * as dynamoDbLib from "../../libs/dynamodb-lib";

import { success, failure } from "../../libs/response-lib";

export async function main(event, context, callback) {
    const data = JSON.parse(event.body);
    const params = {
        TableName: "events",
        Item: {
            userId: event.requestContext.identity.cognitoIdentityId,
            eventId: uuid.v1(),
            content: data.content,
            attachment: data.attachment,
            createdAt: new Date().getTime()
        }
    };
    console.log('event:', event);
    try {
        await dynamoDbLib.call("put", params);
        callback(null, success(params.Item));
    } catch (e) {
        console.log(e);
        callback(
            null,
            failure(
                {
                    status: false
                }
            )
        );
    }
}

All the code is in https://github.com/qazuor/RevolAppBackend

Please help me.

Sorry for my not so good English

jayair commented 6 years ago

@ivanms1 This error is basically saying that the userId is not being passed in. So the best thing would be to console.log what the userId is and see what you are passing in.

@qazuor The serverless.yml in your project is not formatted properly. This is a very annoying issue that most people run into.

Your create looks like this:

  create-event:
    handler: services/events/create.main
    events:
      - http: post /events
        cors: true
        authorizer: aws_iam

Versus what it should look like

  create:
    handler: create.main
    events:
      - http:
          path: notes
          method: post
          cors: true
          authorizer: aws_iam

The issue is that your functions are not using an authorizer (are public), so there is no Cognito Identity Id.

adoolaeghe commented 6 years ago

Hi @jayair, first thanks very much for this tutorials, It has been precious! I am running into this IAM role error when testing the api with apig-test.

Authenticating with User Pool Getting temporary credentials Invalid identity pool configuration. Check assigned IAM roles for this pool.

The message is very obvious, I have checked multiple times my IAM roles from the identity pool as well as the policy statement and the relationship with the user pool. But hard to debug the origin of the error...

If this is a common error, it would be grateful if you have a hint to fix this. Thanks !

jayair commented 6 years ago

@adoolaeghe Yeah these are super annoying to deal with. In this chapter - https://serverless-stack.com/chapters/debugging-serverless-api-issues.html, we talk about using the Policy Simulator to help you debug it. Give it a try and let me know how it goes.

adoolaeghe commented 6 years ago

@jayair Thank for your response. I followed the policy simulator and my policy role does return an Accepted response.

In doubt of the wrong setup, I re-followed the steps with a different AWS account, and I am still getting the same error at the end, which is getting very curious...

brianmade commented 6 years ago

Just checking in on this, which I've just encountered:

Unable to import module 'create': Error
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/var/task/create.js:1:1474)
at n (/var/task/create.js:1:220)
at Object.<anonymous> (/var/task/create.js:1:1659)
at n (/var/task/create.js:1:220)
at /var/task/create.js:1:641
at Object.<anonymous> (/var/task/create.js:1:651)

I see that the previous solution was to revert to serverless 1.17.0 - I'm on 1.26.0 - is the solution really to roll all the way back to .17??

Perhaps it's time to consider an entirely different approach if serverless and webpack just aren't going to play nicely? Perhaps I'm misreading the actual issue involved?

rgandco commented 6 years ago

Seconding @brianmade I am on Serverless 1.26.0 and experiencing the same issues as @tsdorsey originally posted last year - rolling back to 1.17.0 doesn't seem like a solution, more a temporary fix.

Has anyone else succeeded in getting later versions of Serverless to play nicely with Babel and Webpack?

rgandco commented 6 years ago

This is probably not the best way to accomplish this in the long term, but after reading serverless-webpack's guide on forced-inclusion I have edited my serverless.yml as follows to force the inclusion of babel-runtime:

Previously it was:

custom:
  webpackIncludeModules: true

Which packaged as:

Entrypoint calculators = calculators.js
Entrypoint handler = handler.js
   [0] external "babel-runtime/core-js/json/stringify" 42 bytes {0} {1} [built]
   [1] ./handler.js 1020 bytes {0} [built]
   [2] ./libs/response-lib.js 721 bytes {1} [built]
   [3] ./calculators.js 1.98 KiB {1} [built]
Serverless: No external modules needed

Then errorred as:

Thu Mar 01 12:25:28 UTC 2018 : Endpoint response body before transformations: {"errorMessage":"Cannot find module 'babel-runtime/core-js/json/stringify'","errorType":"Error","stackTrace":["Function.Module._load (module.js:417:25)","Module.require (module.js:497:17)","require (internal/module.js:20:19)","Object.defineProperty.value (/var/task/calculators.js:1:676)","n (/var/task/calculators.js:1:220)","Object.<anonymous> (/var/task/calculators.js:1:1159)","n (/var/task/calculators.js:1:220)","/var/task/calculators.js:1:641","Object.<anonymous> (/var/task/calculators.js:1:650)"]}

Following the webpack guidance on forcing includes:

custom:
  webpackIncludeModules:
    forceInclude:
      - babel-runtime

Which packages as:

Entrypoint calculators = calculators.js
Entrypoint handler = handler.js
   [0] external "babel-runtime/core-js/json/stringify" 42 bytes {0} {1} [built]
   [1] ./handler.js 1020 bytes {0} [built]
   [2] ./libs/response-lib.js 721 bytes {1} [built]
   [3] ./calculators.js 1.98 KiB {1} [built]
Serverless: Package lock found - Using locked versions
Serverless: Packing external modules: babel-runtime@^6.26.0
tsdorsey commented 6 years ago

@rgandco I'm on 1.26.0 and it's working just fine. I don't pretend to know which switch you need to flip to get this to work but I can show you a very boiled down project I just published showing how I'm using cross stack references which uses webpack and babel to do just what you're trying to do.

Head over to https://github.com/tsdorsey/myMultiStackResources or https://github.com/tsdorsey/myMultiStackApi (doesn't matter which)

Look at the following files: .babelrc and webpack.config.js These files will be identical in both repos. Also look at serverless.yml

My gut says you need the transform-runtime babel plugin.

I have stood on the shoulders of others to put those files together but I know they work to include the babel-runtime elements that are needed.

rgandco commented 6 years ago

@tsdorsey I've mirrored your .babelrc and webpack.config.js to the letter. I've aligned your serverless.yml with mine for all the relevant areas of configuration.

Still doesn't package babel-runtime or any other external modules, still generates the same error when run within Lambda (but not locally as the modules exist).

Could it be an OS specific issue? I'm deploying from a Windows 10 laptop shrug. Clutching at straws.

tsdorsey commented 6 years ago

@rgandco I Didn't think it would matter but I tried moving the babel-runtime into devDependencies but it still works for me.

I'm on macOS 10.12.6

Could you clone the Resources repo (the API one requires the Resources stack to be deployed) and run yarn install then ./sls package --verbose

I get:

Serverless: Using multi-compile (individual packaging)
Serverless: Bundling with Webpack...
Time: 692ms
                  Asset     Size  Chunks             Chunk Names
src/handlers/cognito.js  3.36 kB       0  [emitted]  src/handlers/cognito
   [0] ./src/handlers/cognito.js 707 bytes {0} [built]
   [1] external "babel-runtime/helpers/asyncToGenerator" 42 bytes {0} [not cacheable]
Serverless: Fetch dependency graph from [redacted]/resources/package.json
Serverless: Packing external modules: babel-runtime@6.26.0
Serverless: Package took [2504 ms]
Serverless: Copy modules: [redacted]/resources/.webpack/cognitoAutoConfirm [651 ms]
Serverless: Prune: [redacted]/resources/.webpack/cognitoAutoConfirm [577 ms]
Serverless: Zip function: [redacted]/resources/.webpack/cognitoAutoConfirm [1008 ms]
Serverless: Packaging service...
Serverless: Remove [redacted]/resources/.webpack
tzlukoma commented 6 years ago

I am unable to get this test to pass.
I get the following error: { status: 502, statusText: 'Bad Gateway', data: { message: 'Internal server error' }

When I looked further into what might be going on, I realized that my Lambda function for create is not working. When I run the test in the AWS console for the function, I get the following error:

{
  "errorMessage": "Cannot find module 'babel-runtime/regenerator'",
  "errorType": "Error",
  "stackTrace": [
    "Module.require (module.js:497:17)",
    "require (internal/module.js:20:19)",
    "Object.<anonymous> (/var/task/create.js:1:1474)",
    "n (/var/task/create.js:1:220)",
    "Object.<anonymous> (/var/task/create.js:1:1659)",
    "n (/var/task/create.js:1:220)",
    "/var/task/create.js:1:641",
    "Object.<anonymous> (/var/task/create.js:1:651)"
  ]
}

I am on the latest versions of both Serverless and NPM and am truly stumped.

tzlukoma commented 6 years ago

@rgandco - the force include solution worked for me ... thank you so much!

rgandco commented 6 years ago

@tsdorsey Short update. Cloned your repo and followed your instructions and it works exactly as expected, my day is a bit all over the place today but I'm going to do a comparison of my project and yours and then report back.

rgandco commented 6 years ago

@tsdorsey The only differences I can really see are:

  1. I have versionFunctions set to false
  2. I have endpointType set to REGIONAL

(Removing these made no difference)

  1. You're using yarn for your package lock, I'm using straight npm package.lock
  2. You have an sls script that sets some environment variables, and I don't - which might be why I'm getting the following warning on my package:
   Asset      Size  Chunks             Chunk Names
users.js  1.65 KiB       0  [emitted]  users
Entrypoint users = users.js
   [0] ./config.js 208 bytes {0} [built]
   [1] external "amazon-cognito-identity-js" 42 bytes {0} [built]
   [2] external "babel-runtime/core-js/json/stringify" 42 bytes {0} [built]
   [3] ./libs/response-lib.js 721 bytes {0} [built]
   [4] external "babel-runtime/core-js/promise" 42 bytes {0} [built]
   [5] ./users.js 1.36 KiB {0} [built]

WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.
Serverless: Fetch dependency graph from [redacted]\package.json
Serverless: No external modules needed
rgandco commented 6 years ago

@tsdorsey Actually - I'm using a different version of webpack too - I'm on ^4.3.0 and you're on 3.11.0