sst / guide

Repo for guide.sst.dev
https://guide.sst.dev
MIT License
3.68k stars 446 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

yashg5 commented 7 years ago

Can you give us example screen shots to test API with postman using AWS signature? thanks in advance

jayair commented 7 years ago

@yashg5 I'm not too familiar with using Postman. Perhaps somebody else can give it a try.

marshallbunch commented 7 years ago

First off, thanks a ton for your tutorials. I went through the previous and now the revised. You're doing great work.

For some reason I'm getting an error when testing the apis:

Error: Invalid UserPoolId format.

at new CognitoUserPool (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\amazon-cognito-identity-js\lib\CognitoUserPool.js:56:13)
at authenticate (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\index.js:70:18)
at Object.<anonymous> (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\index.js:155:1)

I can't really think of a reason why I would be experiencing this problem. I've had no problems for any of the tests I've done so far that used the same user-pool-id.

Any chance you could provide a sample apig-test call with actual values?

jayair commented 7 years ago

@marshallbunch Here is a sample one that I was using. I altered some of the values around but the format should be like so.

apig-test \
--username='admin@example.com' \
--password='Passw0rd!' \
--user-pool-id='us-east-1_YBhdXYvix' \
--app-client-id='29qwoeorti0ctjkur5h91lkw5g' \
--cognito-region='us-east-1' \
--identity-pool-id='us-east-1:565cc505-5486-4278-bf0f-9736p9apq8m5' \
--invoke-url='https://w5z1hluqmp5.execute-api.us-east-1.amazonaws.com/test' \
--api-gateway-region='us-east-1' \
--path-template='/notes' \
--method='POST' \
--body='{"content":"hello world","attachment":"hello.jpg"}'
marshallbunch commented 7 years ago

No cigar. Won't make it past the user-pool-id.

jayair commented 7 years ago

@marshallbunch Hmm can I see the complete output from the command?

marshallbunch commented 7 years ago

Sure:

C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\amazon-cognito-identity-js\lib\CognitoUserPool.js:56
      throw new Error('Invalid UserPoolId format.');
      ^

Error: Invalid UserPoolId format.
    at new CognitoUserPool (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\amazon-cognito-identity-js\lib\CognitoUserPool.js:56:13)
    at authenticate (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\index.js:70:18)
    at Object.<anonymous> (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\index.js:155:1)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:427:7)
manubhat90 commented 7 years ago

For beginners it might be helpful to specify that YOUR_API_GATEWAY_URL should include the stage-name (prod in the example).

"https://ly55wbovq4.execute-api.us-east-1.amazonaws.com/prod"

marshallbunch commented 7 years ago

did that as well.

jayair commented 7 years ago

@marshallbunch Can you show me the full command you used as well? I'm not too familiar with the shell in Windows but let's take a look.

@manubhat90 Good catch. It would work either way but that can be confusing.

marshallbunch commented 7 years ago

@jayair It is most definitely a syntax problem for the shell in windows. I got past the "invalid UserPoolId" error by getting rid of all the \ and the = and '. The current error is that it doens't like the json in the body content.

apig-test --username admin@example.com --password Passw0rd! --user-pool-id us-east-1_HwIVtcRh2 --app-client-id 34bb7b87t6rtc387foiletrldf --cognito-region us-east-1 --identity-pool-id us-east-1:285f61b7-8a95-4596-90ce-7f7e1848c2ed --invoke-url https://6xosj8ww6h.execute-api.us-east-1.amazonaws.com/prod/words --api-gateway-region us-east-1' --path-template /words' --method POST --body {"content":"hello world","attachment":"hello.jpg"}
Authenticating with User Pool
Getting temporary credentials
Making API request
C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\aws-sdk\lib\request.js:31
            throw err;
            ^

SyntaxError: Unexpected token c in JSON at position 1
    at JSON.parse (<anonymous>)
    at makeRequest (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\index.js:131:19)
    at C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\index.js:114:5
    at C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\aws-sdk\lib\credentials.js:123:23
    at Response.<anonymous> (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\aws-sdk\lib\credentials\cognito_identity_credentials.js:258:7)
    at Request.<anonymous> (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\aws-sdk\lib\request.js:364:18)
    at Request.callListeners (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\aws-sdk\lib\sequential_executor.js:105:20)
    at Request.emit (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\aws-sdk\lib\sequential_executor.js:77:10)
    at Request.emit (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\aws-sdk\lib\request.js:683:14)
    at Request.transition (C:\Users\proet\AppData\Roaming\npm\node_modules\aws-api-gateway-cli-test\node_modules\aws-sdk\lib\request.js:22:10)
jayair commented 7 years ago

@marshallbunch Yeah I think we need to figure out how to format a string as an argument in the command line. And possibly escape the characters properly.

tsdorsey commented 7 years ago

Hey guys. Great walkthrough. Everything went smoothly until it was time to test the API. I'm getting 502 bad gateway back from API Gateway. I looked in the CloudWatch logs and found that it can't import modules.

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:76:18)
at __webpack_require__ (/var/task/create.js:20:30)
at Object.<anonymous> (/var/task/create.js:171:20)

I dug into this more by running the get lambda from the API gateway console dashboard using the test command. I got this:

Endpoint response body before transformations: 
{
  "errorMessage": "Cannot find module 'babel-runtime/regenerator'",
  "errorType": "Error",
  "stackTrace": [
    "require (internal/module.js:20:19)", 
    "Object.<anonymous> (/var/task/list.js:76:18)", 
    "__webpack_require__ (/var/task/list.js:20:30)", 
    "Object.<anonymous> (/var/task/list.js:176:20)", 
    "__webpack_require__ (/var/task/list.js:20:30)", 
    "/var/task/list.js:63:18", 
    "Object.<anonymous> (/var/task/list.js:66:10)"
  ]
}

This led me to look into the file being uploaded to S3 by serverless deploy and found that they didn't include webpack. I've attached a screenshot of the unzipped file sent to S3 and the files built by using serverless webpack. As you can see, the node_modules folder is very different between them.

screenshot 2017-07-21 15 41 29

Some of the results of serverless deploy:

$ serverless deploy
Serverless: Bundling with Webpack...
Time: 1698ms
     Asset     Size  Chunks             Chunk Names
 create.js  7.54 kB       0  [emitted]  create
 update.js  7.41 kB       1  [emitted]  update
   list.js  7.11 kB       2  [emitted]  list
    get.js  7.06 kB       3  [emitted]  get
 delete.js  6.84 kB       4  [emitted]  delete
handler.js  3.35 kB       5  [emitted]  handler
   [0] external "babel-runtime/core-js/json/stringify" 42 bytes {0} {1} {2} {3} {4} {5} [not cacheable]
   [1] external "babel-runtime/regenerator" 42 bytes {0} {1} {2} {3} {4} [not cacheable]
   [2] external "babel-runtime/helpers/asyncToGenerator" 42 bytes {0} {1} {2} {3} {4} [not cacheable]
   [3] ./lib/dynamodb-lib.js 652 bytes {0} {1} {2} {3} {4} [built]
   [4] external "aws-sdk" 42 bytes {0} {1} {2} {3} {4} [not cacheable]
   [5] ./lib/response-lib.js 721 bytes {0} {1} {2} {3} {4} [built]
   [6] ./create.js 2.99 kB {0} [built]
   [7] external "uuid" 42 bytes {0} [not cacheable]
   [8] ./delete.js 2.37 kB {4} [built]
   [9] ./get.js 2.58 kB {3} [built]
  [10] ./handler.js 696 bytes {5} [built]
  [11] ./list.js 2.61 kB {2} [built]
  [12] ./update.js 2.9 kB {1} [built]
Serverless: Packing external modules: babel-runtime@6.23.0, uuid@3.1.0
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (14.28 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
......................................
Serverless: Stack update finished...
Service Information
service: notes-app-api
stage: prod
region: us-west-2
api keys:
  None
endpoints:
  ---
functions:
  create: notes-app-api-prod-create
  list: notes-app-api-prod-list
  get: notes-app-api-prod-get
  update: notes-app-api-prod-update
  delete: notes-app-api-prod-delete

Any help would be very much appreciated.

jayair commented 7 years ago

@tsdorsey Thanks for the details. As a quick sanity check, can I see your package.json and serverless.yml?

tsdorsey commented 7 years ago

@jayair I should have done this before I posted. https://github.com/tsdorsey/sls-notes-app

I have serverless-dynamodb-local and serverless-offline in my package file but I'm not using them at the moment. I planned to do that later.

marshallbunch commented 7 years ago

@tsdorsey Good catch. It appears I'm experiencing the same issue.

tsdorsey commented 7 years ago

@marshallbunch and @jayair I'm newish to webpack. Do you think you could point me in a direction so I could try to help figure this out? Got any gut feelings?

tsdorsey commented 7 years ago

Ok, so I watched the folders as I ran serverless package and the .webpack folder is created with the dependencies in the node_modules folder as expected. Then the zip file is made and the .webpack folder is cleaned up. I have been reading through the package plugin; I'm suspect of the excludes directive but the aren't logged... :(

navinkumarr commented 7 years ago

Getting 403 response

Authenticating with User Pool
Getting temporary credentials
Making API request
{ status: 403,
  statusText: 'Forbidden',
  data: { message: 'Forbidden' } }
Jonarod commented 7 years ago

Yeah I get the same response...

{ status: 403,
  statusText: 'Forbidden',
  data: { Message: 'User: arn:aws:sts::907468717626:assumed-role/Cognito_notesidentitypoolAuth_Role/CognitoIdentityCredentials is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-2:********7626:ux5xagukr9/prod/POST/notes' } }

I guess we forgot some tweaks that are not in the code, but rather in the aws console.

Jonarod commented 7 years ago

Ok, I got it working. Basically, I deleted my Federated Identity Pool and recreated it from scratch following this section:

http://serverless-stack.com/chapters/create-a-cognito-identity-pool.html

Note that after doing so, I got these messes:

After that, I got correct 200 status.

Hope it helps

mikhael28 commented 7 years ago

I'm not able to clear this test - if I put in all of my information in as a string, I get the cmd line response: 'Authenticating with User Pool User does not exist'

Which makes no sense, because the user definitely exists - I created one with the same default credentials as in the example and a seperate one, which I used to create, update, delete the event.json file throughout the tutorial.

When I remove all the semi-colons from the data, it runs through saying: 'Authenticating with User Pool' Getting temporary credential Making API request

And then gives me the same JSON token error as the other commenter upstairs!

When I try just taking the string out the username and password, and keeping the rest of the strings there (and some variations) I get this error message: Authenticating with UserPool Getting temporary credentials Inaccessible host: cognito-identity.xn--us-east-2-499dua.amazonaws.com'. This service may not be available in the‘us-east-2’' region.

However, from looking at AWS documentation, Cognito Identity should be available in US-East-2... Halp!

jayair commented 7 years ago

@tsdorsey I just tried your repo and I got it to deploy and call it fine. Of course the call failed because I don't have the IAM roles set up properly to do this. But It's calling everything fine.

screen shot 2017-07-22 at 3 03 29 pm screen shot 2017-07-22 at 3 04 29 pm

I suspect there is something going on on your local. Can you try the following and check the versions you are running?

screen shot 2017-07-22 at 3 05 42 pm
jayair commented 7 years ago

@marshallbunch Are you seeing the same error as @tsdorsey? If you go into your CloudWatch logs do you see the same error (Unable to import module 'create': Error)?

jayair commented 7 years ago

@Jonarod Yeah that error sounds like the IAM Role was not set properly. Thanks for reporting back with detail. I'm sure it'll help folks that run into something similar.

jayair commented 7 years ago

@navinkumarr Your issue sounds like the issue @Jonarod ran into. You can check if the IAM Role has been set properly by going to your AWS Console > IAM > Roles (in the sidebar) > Cognito_notesidentitypoolAuth_Role > Scroll down and click on Show Policy.

screen shot 2017-07-22 at 3 14 54 pm

And make sure the policy looks like the one in the tutorial.

jayair commented 7 years ago

@mikhaelbendavid Are you on Windows as well like @marshallbunch? Can I see the full command you used that generated that last error?

thesavvygreek commented 7 years ago

@jayair I'm getting

{ status: 502,
  statusText: 'Bad Gateway',
  data: { message: 'Internal server error' } }

Digging deeper into Cloudwatch, specifically the create lambda function, I get

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:76:18)
at __webpack_require__ (/var/task/create.js:20:30)
at Object.<anonymous> (/var/task/create.js:167:20)
at __webpack_require__ (/var/task/create.js:20:30)
at /var/task/create.js:63:18
at Object.<anonymous> (/var/task/create.js:66:10)

My package.json is:

{
  "name": "notes-app-api",
  "version": "1.0.0",
  "description": "",
  "main": "handler.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.25.0",
    "babel-loader": "^7.1.1",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-3": "^6.24.1",
    "glob": "^7.1.2",
    "serverless-webpack": "^2.0.0",
    "webpack": "^3.3.0",
    "webpack-node-externals": "^1.6.0"
  },
  "dependencies": {
    "babel-runtime": "^6.23.0"
  }
}

I haven't done any digging into the packaging that serverless deploy produces but this is to confirm I'm experiencing the same issue as @tsdorsey is experiencing.

jayair commented 7 years ago

@thesavvygreek Can I see what version of Node, NPM, and Serverless you are using?

thesavvygreek commented 7 years ago

@jayair Sure

jayair commented 7 years ago

@thesavvygreek @tsdorsey Thanks for that. Figured it out!

It's a Serverless Framework bug. They broke it with their latest release. Here is the issue somebody else opened for it - https://github.com/serverless/serverless/issues/3972

For now you can use 1.17.0 by doing the following. I'll add this to the tutorial.

$ npm uninstall -g serverless
$ npm install -g serverless@1.17.0

And then serverless deploy again.

jayair commented 7 years ago

@thesavvygreek Btw, your package.json is missing this line for some reason - https://github.com/AnomalyInnovations/serverless-stack-demo-api/blob/master/package.json#L34

thesavvygreek commented 7 years ago

@jayair Ah nice one, it works! Thanks for the help!

bradodarb commented 7 years ago

I'm running into a 403 as well. I tried @Jonarod 's approach and carefully recreated the pool, but no dice. I get this in the terminal: Authenticating with User Pool Getting temporary credentials Making API request { status: 403, statusText: 'Forbidden', data: { message: 'Forbidden' } }

tsdorsey commented 7 years ago

@jayair thank you so much for the thorough and quick help. @marshallbunch did you get things squared away using this info?

I had a moment of horror when I moved to serverless@1.17.0 and it still failed. Then I got to thinking about it and realized that I was using an environment variable for the region in my dynamodb-lib file. When I hard coded that to be us-west-2 The test came back successful. I know aws-lambda can do environment variables but I'll sort that out later.

For posterities sake I was running the following versions: node -v 8.1.3 npm -v 5.0.3 serverless -v 1.18.0

jayair commented 7 years ago

@bradodarb Can you take a look at your Cloudwatch logs to see what it says? Also, can you post the IAM policy that you have (follow these instructions https://github.com/AnomalyInnovations/serverless-stack-com/issues/112#issuecomment-317204545)?

bradodarb commented 7 years ago

Thanks for taking a look, @jayair.

I enabled logging on the API stage but see nothing in cloudwatch.

I did triple check my setting as you suggested and confirm that I have this inline role:

    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::m4-user-assets/${cognito-identity.amazonaws.com:sub}*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:*:ps8mmgaj2c/*"
            ]
        }
      ]
  }
bradodarb commented 7 years ago

I tried switching the test parameters up a bit and instead of breaking the test url up between invoke-url and path-template as in the example I used the invoke-uRL from the API Gateway console and set the template to '/'

So instead of this:

apig-test \
--username='admin@example.com' \
--password='Passw0rd!' \
--user-pool-id='us-east-1_***********' \
--app-client-id='*************************' \
--cognito-region='us-east-1' \
--identity-pool-id='us-east-1:******************************************' \
--invoke-url='https://ps8mmgaj2c.execute-api.us-east-1.amazonaws.com/dev' \
--api-gateway-region='us-east-1' \
--path-template='/mail' \
--method='POST' \
--body='{"content":"hello world","attachment":"hello.jpg"}

I tried this:

apig-test \
--username='admin@example.com' \
--password='Passw0rd!' \
--user-pool-id='us-east-1_***********' \
--app-client-id='*************************' \
--cognito-region='us-east-1' \
--identity-pool-id='us-east-1:******************************************' \
--invoke-url='https://ps8mmgaj2c.execute-api.us-east-1.amazonaws.com/dev/mail' \
--api-gateway-region='us-east-1' \
--path-template='/' \
--method='POST' \
--body='{"content":"hello world","attachment":"hello.jpg"}

And I seemed to get more information back:

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/dev/mailC%3A/Program%2520Files/Git/\n\naccept:application/json\ncontent-type:application/json\nhost:ps8mmgaj2c.execute-api.us-east-1.amazonaws.com\nx-amz-date:2017
0724T154352Z\n\naccept;content-type;host;x-amz-date\n3a99f7c41ea871222ce9eb05cc8c7a5bbfc8e141bbb3c3999cff381d1462d448\'\n\nThe String-to-Sign should have been\n\'AWS4-HMAC-SHA256\n20170724T154352Z\n20170724/us-east-
1/execute-api/aws4_request\nb85c01d15750e6db44ea387c0ac4dec6bfd39b6cd8a245e32141e97b82955917\'\n' } }

This prompted me to have a look at all settings in the test parameters and everything validated to be using the correct variables.

jayair commented 7 years ago

@bradodarb The IAM Policy looks good. Can you post your serverless.yml as well? Let's make sure things look okay.

bradodarb commented 7 years ago

@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
jugglingcats commented 7 years ago

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!

jayair commented 7 years ago

@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?

jugglingcats commented 7 years ago

Sorry I meant 403 Forbidden...

neowulf commented 7 years ago

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' } }
jayair commented 7 years ago

@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.

limifont commented 7 years ago

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' } }

bradodarb commented 7 years ago

@jayair

Here's my repo: https://github.com/bradodarb/m4-user-mail-api

deepseafishing commented 7 years ago

@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?

mikhael28 commented 7 years ago

@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'

jcowley commented 7 years ago

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.