Comments for Test the APIs

From @bradodarb on Mon Jul 24 2017 19:33:27 GMT+0000 (UTC)

@jayair , I’m sure I’m doing/not doing something silly as I’m pretty novice with aws still. I really appreciate your help.


service: m4-user-mail-api

# 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: dev
  region: us-east-1

  # 'iamRoleStatement' defines the permission policy for the Lambda function.
  # In this case Lambda functions are granted with permissions to access DynamoDB.
  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:
  # Defines an HTTP API endpoint that calls the main function in create.js
  # - path: url path is /mail
  # - method: POST request
  # - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
  #     domain api call
  # - authorizer: authenticate using the AWS IAM role
  create:
    handler: create.main
    events:
      - http:
          path: mail
          method: post
          cors: true
          authorizer: aws_iam
  get:
    # Defines an HTTP API endpoint that calls the main function in get.js
    # - path: url path is /mail/{id}
    # - method: GET request
    handler: get.main
    events:
      - http:
          path: mail/{id}
          method: get
          cors: true
          authorizer: aws_iam
  list:
    # Defines an HTTP API endpoint that calls the main function in list.js
    # - path: url path is /notes
    # - method: GET request
    handler: list.main
    events:
      - http:
          path: mail
          method: get
          cors: true
          authorizer: aws_iam
  update:
    # Defines an HTTP API endpoint that calls the main function in update.js
    # - path: url path is /mail/{id}
    # - method: PUT request
    handler: update.main
    events:
      - http:
          path: mail/{id}
          method: put
          cors: true
          authorizer: aws_iam
  delete:
    # Defines an HTTP API endpoint that calls the main function in delete.js
    # - path: url path is /mail/{id}
    # - method: DELETE request
    handler: delete.main
    events:
      - http:
          path: mail/{id}
          method: delete
          cors: true
          authorizer: aws_iam

From @jugglingcats on Mon Jul 24 2017 21:08:24 GMT+0000 (UTC)

The tutorial is great and must have already saved many 1,000s of person hours - thank you.

Unfortunately I have the same issue as @bradodarb. Always get a 404 when using apig-test. Have tried carefully recreating the identity pool. Pretty sure my IAM role/policy is correct. Must be something simple!

From @jayair on Mon Jul 24 2017 21:27:05 GMT+0000 (UTC)

@bradodarb That looks good as well. The only thing I can do now is try out your code. Can you put it up on GitHub like @tsdorsey had done?

@jugglingcats Thanks for the kind words. The 404 seems like a different issue. Can I see the full output for the apig-test command?

From @jugglingcats on Mon Jul 24 2017 21:29:23 GMT+0000 (UTC)

Sorry I meant 403 Forbidden…

From @neowulf33 on Mon Jul 24 2017 22:27:29 GMT+0000 (UTC)

Same issue as @bradodarb @jugglingcats

  1. Can we turn on cloudwatch for API gateway?
  2. Is the 403 being returned by the API gateway or the lambda function?
  3. When the IAM policy gets updated - do the permission changes reflect immediately?
  4. Looks like there’s a policy simulator located here - the policy seems to work when accessing the API gateway endpoint for the POST method but still get the 403 when using apig-test. Here’s my output:
Authenticating with User Pool
Getting temporary credentials
Making API request
{ status: 403,
  statusText: 'Forbidden',
  data: { message: 'Forbidden' } }

From @jayair on Mon Jul 24 2017 23:05:49 GMT+0000 (UTC)

@neowulf33 Thanks for the details.

Yeah you can turn on CloudWatch for API Gateway from the console under API Gateway. But it does not log some auth related errors. So I’m suspecting this is happening before it hits Lambda. The permission changes are not immediate but relatively quick. I’d say a couple of minutes.

Can you put up your repo? I want to try it out myself and see whats going on.

From @limifont on Mon Jul 24 2017 23:36:51 GMT+0000 (UTC)

I’m getting an unauthorized response from this test and I’m not sure why. Anyone else get this, too?
{ status: 401, statusText: 'Unauthorized', data: { message: 'Unauthorized' } }

From @bradodarb on Tue Jul 25 2017 03:16:10 GMT+0000 (UTC)

@jayair

Here’s my repo:

From @deepseafishing on Tue Jul 25 2017 04:22:52 GMT+0000 (UTC)

@jayair Hi, Jayair. I’m preparing my tech talk on AWS lambda and following your tutorial. This is really helpful. Thank you so much.
I deployed the API ok. but testing API keeps giving me this error.

{ status: 500,
statusText: ‘Internal Server Error’,
data: { status: false } }

In cloudWatch logs it says


message: 'User: arn:aws:sts::721932120760:assumed-role/notes-app-api-prod-us-east-2-lambdaRole/notes-app-api-prod-create is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:us-east-2:721932120760:table/notes',
code: 'AccessDeniedException',
time: 2017-07-25T04:17:50.292Z,
requestId: '***********',
statusCode: 400,

my serverless.yml looks like this


service: notes-app-api # NOTE: update this with your service name

 Use serverless-webpack plugin to transpile ES6 / ES7
plugins:
  - serverless-webpack
 Enable auto-packing of external modules
custom:
  webpackIncludeModules: true

 You can pin your service to only deploy with a specific Serverless version
 Check out our docs for more details
 frameworkVersion: "=X.X.X"

provider:
  name: aws
  runtime: nodejs6.10
  stage: prod
  region: us-east-2

 you can add statements to the Lambda function's IAM Role here
 'iamRoleSTatement' defines the permission policy for the Lambda function .
 In this case Lambda functions are granted with permissions to access DynamoDB.
iamRoleStatements:
  - Effect: Allow
    Action:
      - dynamodb:DescribeTable
      - dynamodb:Query
      - dynamodb:Scan
      - dynamodb:GetItem
      - dynamodb:PutItem
      - dynamodb:UpdateItem
      - dynamodb:DeleteItem
    Resource: "arn:aws:dynamodb:us-east-2:*:*"

I guess I hadn’t figured it correctly about some permissions here but I can’t find the reason why.
do you have any idea about this problem?

From @mikhaelbendavid on Tue Jul 25 2017 04:28:43 GMT+0000 (UTC)

@jayair - Here is the full command:
Michaels-MacBook-Pro:serverlessblog Mikha-el$ apig-test \

–username=‘mlitchev@protonmail.ch’
–password=‘Passw0rd!’
–user-pool-id=‘us-east-2_t6tTEb8QD’
–app-client-id=‘52vsuvcodusl9lmeqcr4maq4ck’
–cognito-region=‘us-east-2’
–identity-pool-id=‘us-east-2:a3fca15d-934a-4c40-915a-9a147e7010a4’
–invoke-url=‘https://2mf1f9pxi7.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”}’
Authenticating with User Pool
User does not exist.

My repo is here: https://github.com/mikhaelbendavid/serverlessblog

I’m on MacOS! I don’t think there is anything wrong with my serverless.yml - I skipped ahead to the part where I am creating new notes to the API, and I am getting an issue that I have a TypeError: ‘unable to fetch’

From @jcowley on Tue Jul 25 2017 14:14:31 GMT+0000 (UTC)

Also getting the same error as @bradodarb, @jugglingcats, and @neowulf33

Authenticating with User Pool
Getting temporary credentials
Making API request
{ status: 403,
  statusText: 'Forbidden',
  data: { message: 'The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n\'POST\n/prod/notes\n\naccept:application/json\ncontent-type:application/json\nhost:1lu7ffc9hk.execute-api.us-west-2.amazonaws.com\nx-amz-date:20170725T140608Z\n\naccept;content-type;host;x-amz-date\n3a99f7c41ea871222ce9eb05cc8c7a5bbfc8e141bbb3c3999cff381d1462d448\'\n\nThe String-to-Sign should have been\n\'AWS4-HMAC-SHA256\n20170725T140608Z\n20170725/us-west-2/execute-api/aws4_request\nb672c9c637363a6d64ffdcdc78a2d76d7677b6cbf120411a8709a46ab27761e0\'\n' } }

Additional piece of info for me is that I was mid-way through the tutorial when the switch was made to use IAM as an authorizer. So I had to go back and make changes from looking at the PR. I wouldn’t be at all surprised if I missed something.

From @jcowley on Tue Jul 25 2017 17:34:10 GMT+0000 (UTC)

Okay, for me the signature issue was caused by having a trailing slash on the invoke-url, e.g.:

...
--invoke-url='https://ly55wbovq4.execute-api.us-east-1.amazonaws.com/prod/'
--path-template='/notes' \
...

The invoke url and path are combined by aws-api-gateway-cli-test and resulted in a double slash in the URL, which would (I guess) result in a different signature than the one AWS would expect for the request.

Removing the slash after prod fixed it for me:

...
--invoke-url='https://ly55wbovq4.execute-api.us-east-1.amazonaws.com/prod'
--path-template='/notes' \
...

So maybe double check your invoke-url and path-template.

1 Like

From @jayair on Tue Jul 25 2017 17:40:19 GMT+0000 (UTC)

@bradodarb Just tried your repo. It worked fine for me.

screen shot 2017-07-25 at 1 32 31 pm

This error is because of the code but all the auth stuff worked okay.

Can I get the name of the IAM Policy in your Identity Pool? Or if you could post a screenshot like so.

From @jayair on Tue Jul 25 2017 18:09:49 GMT+0000 (UTC)

@bradodarb One other thing to try is the Policy Simulator like @neowulf33 suggested - https://policysim.aws.amazon.com/home/index.jsp?#roles

Pick your IAM Role, Select a Service (API Gateway), Select an action (Invoke), Add the ARN and Run Simulation.

From @jayair on Tue Jul 25 2017 18:12:51 GMT+0000 (UTC)

@jugglingcats @limifont You guys can try the above as well and let me know how it goes.

From @jayair on Tue Jul 25 2017 18:14:52 GMT+0000 (UTC)

@deepseafishing From looking at your serverless.yml it looks like the iamRoleStatements is on the save level of indentation as the provider. It shouldn’t be so, compare it against the one in the repo to make sure it looks okay.

From @jayair on Tue Jul 25 2017 18:20:17 GMT+0000 (UTC)

@mikhaelbendavid You’d need to make sure the user is created like in this chapter - http://serverless-stack.com/chapters/create-a-cognito-test-user.html

You can also go into the User Pool > Users and groups > and check if the user is enabled and confirmed like so.

From @jayair on Tue Jul 25 2017 18:21:08 GMT+0000 (UTC)

@jcowley Thanks for reporting back!

From @algalvez on Tue Jul 25 2017 18:23:06 GMT+0000 (UTC)

for those having problems with windows cmd, this worked for me:

apig-test --username admin@example.com --password Passw0rd! --user-pool-id YOUR_COGNITO_USER_POOL_ID --app-client-id YOUR_COGNITO_APP_CLIENT_ID --cognito-region YOUR_COGNITO_REGION --identity-pool-id YOUR_IDENTITY_POOL_ID --invoke-url YOUR_API_GATEWAY_URL --api-gateway-region YOUR_API_GATEWAY_REGION --path-template notes --method POST --body "{\"content\":\"hello world\",\"attachment\":\"hello.jpg\"}"

From @jayair on Tue Jul 25 2017 18:27:04 GMT+0000 (UTC)

@algalvez Thanks for posting this. I’m sure it’ll help!