JWT authentication stops working after upgrading from .netcore2.2 to .netcore3.1 - swashbuckle

After upgrading,
In the Swagger UI I can create a bearer token but I get a 401 when I try to use it.
In the error log I see
AuthenticationScheme: "Bearer" was not authenticated
and
"POST" requests are not supported
and
Request successfully matched the route with name 'null' and template
2020-09-01 04:58:25.004 +10:00 [Information] [Microsoft.AspNetCore.Hosting.Diagnostics] [{ Id: 1 }] Request starting HTTP/2.0 POST https://localhost:44348/api/job-management/get-user-counts application/json 18
2020-09-01 04:58:25.005 +10:00 [Debug] [Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler] [{ Id: 9, Name: "AuthenticationSchemeNotAuthenticated" }] AuthenticationScheme: "Bearer" was not authenticated.
2020-09-01 04:58:25.005 +10:00 [Debug] [Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware] [{ Id: 1, Name: "MethodNotSupported" }] "POST" requests are not supported
2020-09-01 04:58:25.005 +10:00 [Debug] [Microsoft.AspNetCore.Rewrite.RewriteMiddleware] [{ Id: 1, Name: "RequestContinueResults" }] Request is continuing in applying rules. Current url is "https://localhost:44348/api/job-management/get-user-counts"
2020-09-01 04:58:25.006 +10:00 [Debug] [Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware] [{ Id: 1, Name: "MethodNotSupported" }] "POST" requests are not supported
2020-09-01 04:58:25.006 +10:00 [Debug] [Microsoft.AspNetCore.Routing.Tree.TreeRouter] [{ Id: 1, Name: "RequestMatchedRoute" }] Request successfully matched the route with name 'null' and template '"api/job-management/get-user-counts"'
I thought of generating a new sample api using VS2019, however I can not find one for JWT
In ConfigureServices I have added
services.AddMvc(option => option.EnableEndpointRouting = false);
How should I go about troubleshooting my issue?
[Update]
I have looked through the Microsoft Upgrade guidelines but am not spotting that I have missed anything.

I found the answer at this question
I had correctly converted to use OpenApiParameter but I had missed the step of
Schema = new OpenApiSchema() { Type = "String" }
I am thinking my question is not a duplicate because the errors I got may assist someone else in finding the answer.

Related

InputTransformer YAML not resolving for event rule

I am aiming to send following format to the data:
{
"headers": {
"Authorization": "Bearer expectedToken"
},
"body": {
"id": "abc",
"status": "ANY",
"preferences": [ [Object] ]
}
}
but struggling with the Input transformer in YAML:
inputTransformer:
inputPathsMap:
expectedToken: '$detail.metadata.someToken'
inputTemplate: '{"headers": {"Authorization": <expectedToken>}}'
And getting this error:
Received response status [FAILED] from custom resource. Message
returned: Event pattern is not valid. Reason: "expectedToken" must be
an object or an array+ +at [Source:
(String)"{"inputTransformer":{"inputPathsMap":{"expectedToken":"$detail.metadata.someToken"},"inputTemplate":"{"headers":
{"Authorization": }}"},"
Trigger is an APIGW with a mapping template that appends a Auth token as part of the metadata, but the target expects it as a header. Is it a viable solution? How can this be resolved to the expected format?
Later Edit: Data being sent from APIGW:
{
detail: {
body: {
id: 'abc',
extraInfo: 'Postman_15:07',
preferences: [Array]
},
metadata: {
service: 'my-service',
status: 'ANY',
someToken: 'Bearer expectedToken'
}
}
}
Could you share an example (scrubbed of personal info) of your event payload - ie the JSON that has the detail, and metadata sub-fields?
You could also try
inputTransformer:
inputPathsMap:
expectedToken: '$detail.metadata.someToken'
inputTemplate: '{"headers": {"Authorization": "Bearer <expectedToken>"}}'
Try it out with an input-path like $.detail.metadata.someToken
If this also doesn't work, as already asked for, give us an example of the event that arrives at the EventBridge itself. If you don't know the event payload you can setup an event rule that forwards the event to a CloudWatch log group so that you can check the logs. (tip: setup the cloudwatch target via AWS console, afaik there are some issues using CloudFormation for this)
Thank you for the suggestions. It looks like the issue was with indentation of the inputTransformer section under eventbridge. That error message was by no means helpful. Final format to match what the target Lambda was expecting was :
inputTransformer:
inputPathsMap:
expectedToken: '$detail.metadata.someToken'
data: '$.detail.body'
inputTemplate: '{"headers": {"Authorization": <expectedToken>}, "body": <data>}'

How to restore from 429 Resource has been exhausted (e.g. check quota)

my questions are simple, I am using PEOPLE API and I have skipped the quota limit for one of the users using the API, the error is only shown when trying to create a new contact for this specific user.
The error says code: 429, message: Resource has been exhausted (e.g. check quota).
How can I restore the user to use the API again?
If the limits are reset every minute, how is it possible that after 3 days the user is still blocked?
I do not want to increase the quota, what I want is to restore the quota again.
Additionally to this in my developer panel there is no indication that I have exceeded the quota which for PEOPLE API is limited to 90 per minute.
My code is:
const request = {
requestBody: contact
}
service.people.createContact(request)
.then((res)=>{
console.log('Done to create a contact', res.data);
})
.catch((err)=>{
console.log('Error', err);
})
And the retuning massage is:
response: {
config: {
url: 'https://people.googleapis.com/v1/people:createContact',
method: 'POST',
paramsSerializer: [Function],
data: [Object],
headers: [Object],
params: [Object: null prototype] {},
validateStatus: [Function],
body: '{"names":[{"familyName":"PASIEGA","givenName":"HOTEL","middleName":"VILLA","unstructuredName":"HOTEL VILLA PASIEGA"}],"addresses":[{"type":"home","streetAddress":"LAS BARRERAS, SN","city":"HOZNAYO","region":"S","postalCode":"39716","country":"ESPAÑA","countryCode":"ES"}],"emailAddresses":[{"value":"reservas#grupolospasiegos.com","type":"work"}],"phoneNumbers":[{"value":"785 52 12 58","type":"Villa Pasiega"},{"value":"785 52 12 58","type":"workFax"}],"biographies":[{"value":"Hotel los Pasiegos - Grupoo los Pasiegos","contentType":"TEXT_PLAIN"}],"urls":[{"value":"http://grupolospasiegos.com/contacto/","type":"profile"}],"organizations":[{"type":"Other","name":"HOTEL VILLA PASIEGA","title":"RESERVA"}],"memberships":[{"contactGroupMembership":{"contactGroupResourceName":"contactGroups/199bb8970e07b6a8"}},{"contactGroupMembership":{"contactGroupResourceName":"contactGroups/55fdbf598e048c03"}},{"contactGroupMembership":{"contactGroupResourceName":"contactGroups/5ee644148f02b901"}}]}',
responseType: 'json'
},
data: { error: [Object] },
headers: {
'alt-svc': 'h3-Q050=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
'cache-control': 'private',
connection: 'close',
'content-encoding': 'gzip',
'content-type': 'application/json; charset=UTF-8',
date: 'Thu, 22 Oct 2020 12:47:16 GMT',
server: 'ESF',
'transfer-encoding': 'chunked',
vary: 'Origin, X-Origin, Referer',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0'
},
status: 429,
statusText: 'Too Many Requests'
},config: {
url: 'https://people.googleapis.com/v1/people:createContact',
method: 'POST',
paramsSerializer: [Function],
data: {
names: [Array],
addresses: [Array],
emailAddresses: [Array],
phoneNumbers: [Array],
biographies: [Array],
urls: [Array],
organizations: [Array],
memberships: [Array]
},
headers: {
'Accept-Encoding': 'gzip',
'User-Agent': 'google-api-nodejs-client/0.7.2 (gzip)',
Authorization: 'Bearer ya29.a0AfH6SMAJtuUp3vLhSXlDVyAd80iQc1D-mYZUD7mENq12vTiegBAV834dTGYbpuuVN9wCpJ0JBB51oMwEozhb9_xoM7s9NTiwqBicNYZAjzPpjLL4MvQUp8b-Oqju8opyNwDAJWCnLvUJ5Bvz266z5H1ZXIpe3_YstXDRzw',
'Content-Type': 'application/json',
Accept: 'application/json'
},
params: [Object: null prototype] {},
validateStatus: [Function],
body: '{"names":[{"familyName":"PASIEGA","givenName":"HOTEL","middleName":"VILLA","unstructuredName":"HOTEL VILLA PASIEGA"}],"addresses":[{"type":"home","streetAddress":"LAS BARRERAS, SN","city":"HOZNAYO","region":"S","postalCode":"39716","country":"ESPAÑA","countryCode":"ES"}],"emailAddresses":[{"value":"reservas#grupolospasiegos.com","type":"work"}],"phoneNumbers":[{"value":"942 525 962","type":"Villa Pasiega"},{"value":"942 525 963","type":"workFax"}],"biographies":[{"value":"Hotel los Pasiegos - Grupoo los Pasiegos","contentType":"TEXT_PLAIN"}],"urls":[{"value":"http://grupolospasiegos.com/contacto/","type":"profile"}],"organizations":[{"type":"Other","name":"HOTEL VILLA PASIEGA","title":"RESERVA"}],"memberships":[{"contactGroupMembership":{"contactGroupResourceName":"contactGroups/199bb8970e07b6a8"}},{"contactGroupMembership":{"contactGroupResourceName":"contactGroups/55fdbf598e048c03"}},{"contactGroupMembership":{"contactGroupResourceName":"contactGroups/5ee644148f02b901"}}]}',
responseType: 'json'
},
code: 429,
errors: [
{
message: 'Resource has been exhausted (e.g. check quota).',
domain: 'global',
reason: 'rateLimitExceeded'
}
]
}
The image below you can see my developer google console and it shows that i only have used 25 createContact request in a period of 2 days with a 100% error message which is the message a post here.
image
By the way thanks for your help.
I have found the solution to the problem and I have to be a bit extensive when explaining the solution.
Each google user has a limit on the number of contacts that can be stored in his contacts.google.com account, the limit is 25,000 contacts, if you exceed this limit the error shown in People API is 429 = Too Many Requests, my user only has 9000 contacts so the limit was not the cause of the problem, but what it had not considered is that a few weeks ago Google added a buttom basket for deleted contacts to contacts.google.com and it looks like that each contact deleted is stored and counted as a contact within contacts.google.com. This is what happened to me.
In summary:
My user has 9,000 visible contacts and 16,000 deleted contacts giving a total of 25,000 contacts causing error 429 to be displayed every time I try to create a new contact.
Solution:
Delete all deleted contacts, and everything should be resolved.
Hope:
Google allows access to People API to the contacts in the deleted basket and that error 429 better explains what it refers to cuz as i see in this case it is not a quota problem.
Important:
Thank you very much to #ale13 for your intent to help, I will leave this here in case future developers face the same problem.

Vue PWA login works in dev but returns 401 in production

I have a Vue.js PWA with a Django Rest Framework backend which works correctly locally on my laptop (using a browser). When I deploy it to production it continues to work correctly when I log in using a browser, however it fails to login when opened as a PWA (ie: on a phone or a PWA saved in a browser).
Here's my login code:
axios
.post("/api/get-token/", user)
.then(res => {
localStorage.setItem('user-token', res.data.token);
axios.defaults.headers.common['Authorization'] = res.data.token;
commit(AUTH_SUCCESS, res.data);
resolve(res);
})
.catch(err => {
commit(AUTH_ERROR, err);
reject(err);
});
As mentioned, everything works locally and in production when logging in via a browser. The problem comes when trying to log in using the PWA.
When trying to login to the PWA, I get the following:
POST https://www.example.com/api/get-token/ 401 (Unauthorized)
Doing a console log of the error received from the server I get:
{
detail: "Invalid token header. No credentials provided."
__proto__: Object
status: 401
statusText: "Unauthorized"
headers: {allow: "POST, OPTIONS", connection: "keep-alive", content-length: "59", content-type: "application/json", date: "Thu, 06 Feb 2020 15:00:11 GMT", …}
config:
url: "/api/get-token/"
method: "post"
data: "{"username":"test#example.com","password":"password"}"
headers:
Accept: "application/json, text/plain, */*"
Authorization: "Token "
Content-Type: "application/json;charset=utf-8"
__proto__: Object
transformRequest: [ƒ]
transformResponse: [ƒ]
timeout: 0
adapter: ƒ (t)
xsrfCookieName: "csrftoken"
xsrfHeaderName: "X-CSRFToken"
maxContentLength: -1
validateStatus: ƒ (t)
}
In production, the following works:
Log into the site using a browser on my laptop or on a phone.
Then open the PWA. This works correctly and I can continue using the PWA.
The only issue comes when trying to log in using the PWA.
Can you log in on a phone locally? I had this problem too once, the problem was that the frontend and backend were not running on the same host. This solved my problem:
devServer: {
proxy: {
'/api': {
target: 'http://localhost:5000'
}
}
}
I eventually figured out the issue. For some reason the following was being POSTed in the header: Authorization: "Token ".
This is really strange because when logging in using the /api/get-token/ there is no token required since this is the login route. Also, it works perfectly from a browser. The only issue is when trying from a PWA.
Anyway, changing the header to explicitly have no value for Authorization fixed the issue as follows: Authorization: ""

CloudFormation API Gateway CORS issue access to XMLHttpRequest blocked

I'm trying to use CloudFormation to create an API Gateway but I have CORS issue with it.
Error on the front-end:
POST https://<>.execute-api.us-east-1.amazonaws.com/prod/<> 500
new:1 Access to XMLHttpRequest at '<>' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The API is created without any issue and I even double check every single page on the console against the working API and find no differences in their Method Request, Integration Request, Integration Response and Method Response for all the methods (including the OPTIONS).
If I remove the resources created by the template and create them manually in the same API gateway then my code works as expected. I've tested with the localhost, front-end code in S3 bucket and PostMan, so I can verify that my front-end code, lambda functions and database are working correctly.
I understand that people have had this issue before but I haven't been able to find any answer that solves my issue.
Here's my template.
Please note that the "method.response.header.Access-Control-Allow-Origin": false actually creates the API with the same settings as the working one.
I also use the code from the correct answer for this question.
Yes, my OPTIONS request has the "Access-Control-Allow-Origin" header.
Update
Following dannymac's answer below. I got these:
I added console.log(event.requestContext); to my Lambda function (written in Node.js).
There are logs for Lambda when I test the function.
2019-06-27T20:07:03.118Z 462b93b2-9d4b-4ed3-bc04-f966fcd034cf Debug CORS issue. Request ID:
2019-06-27T20:07:03.118Z 462b93b2-9d4b-4ed3-bc04-f966fcd034cf undefined
It looks like there is no event.requestContext.
I selected Enable CloudWatch Logs-INFO and Enable Detailed CloudWatch Metrics with CloudWatch log role ARN*:arn:aws:iam::<ID>:role/ApiGatewayCloudWatchLogsRole (it's a role created by AWS) in the API Gateway settings.
However, there is no CloudWatch log for the API Gateway. There's a default log in CloudWatch - Log Groups: /aws/apigateway/welcome
Time (UTC +00:00)
2019-06-27
19:50:55
Cloudwatch logs enabled for API Gateway
It looks like the CloudWatch log didn't pick up the test from API Gateway.
This is what I got from testing the GET method in my API Gateway:
Response Body
{
"message": "Internal server error"
}
Response Headers
{}
Logs
Execution log for request 10d90173-9919-11e9-82e1-dd33dda3b9df
Thu Jun 27 20:20:54 UTC 2019 : Starting execution for request: 10d90173-9919-11e9-82e1-dd33dda3b9df
Thu Jun 27 20:20:54 UTC 2019 : HTTP Method: GET, Resource Path: /notes
Thu Jun 27 20:20:54 UTC 2019 : Method request path: {}
Thu Jun 27 20:20:54 UTC 2019 : Method request query string: {userid=<ID>}
Thu Jun 27 20:20:54 UTC 2019 : Method request headers: {}
Thu Jun 27 20:20:54 UTC 2019 : Method request body before transformations:
Thu Jun 27 20:20:54 UTC 2019 : Endpoint request URI: https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:770402430649:function:test-api-gateway-2-LambdaFunction-1XDONAN3QIY9I/invocations
Thu Jun 27 20:20:54 UTC 2019 : Endpoint request headers: {x-amzn-lambda-integration-tag=... [TRUNCATED]
Thu Jun 27 20:20:54 UTC 2019 : Endpoint request body after transformations: {"resource":"/notes","path":"/notes","httpMethod":"GET","headers":null,"multiValueHeaders":null,"queryStringParameters":{"userid":"<USERID>"},"multiValueQueryStringParameters":{"userid":["<USERID>"]},"pathParameters":null,"stageVariables":null,"requestContext":{"path":"/notes","accountId":"<ID>"...,"identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"test-invoke-api-key","principalOrgId":null,"cognitoAuthenticationType":null,"userArn":"<ARN>","apiKeyId":"test-invoke-api-key-id","userAgent":..."test [TRUNCATED]
Thu Jun 27 20:20:54 UTC 2019 : Sending request to https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:<ID>:function:test-api-gateway-2-LambdaFunction-<STRING>/invocations
Thu Jun 27 20:20:54 UTC 2019 : Received response. Status: 403, Integration latency: 6 ms
Thu Jun 27 20:20:54 UTC 2019 : Endpoint response headers: {Date=Thu, 27 Jun 2019 20:20:54 GMT, Content-Length=130, Connection=keep-alive, x-amzn-RequestId=<ID>}
Thu Jun 27 20:20:54 UTC 2019 : Endpoint response body before transformations: <AccessDeniedException>
<Message>Unable to determine service/operation name to be authorized</Message>
</AccessDeniedException>
Thu Jun 27 20:20:54 UTC 2019 : Lambda invocation failed with status: 403. Lambda request id: feb22917-0dea-4f91-a274-fb6b85a69121
Thu Jun 27 20:20:54 UTC 2019 : Execution failed due to configuration error:
Thu Jun 27 20:20:54 UTC 2019 : Method completed with status: 500
I've also exported both the working and not working API Gateway in Swagger 2. The only difference is:
// working one:
"x-amazon-apigateway-any-method": {
"produces": [
"application/json"
],
"parameters": [
{
"name": "noteid",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
}
},
"security": [
{
"mobile-notes-api-authorizer": []
}
]
}
// not working one:
"x-amazon-apigateway-any-method": {
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
}
},
"security": [
{
"test-api-gateway-2-authorizer": []
}
]
}
They both have:
"headers": {
"Access-Control-Allow-Origin": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Headers": {
"type": "string"
}
}
I've tried to use the Swagger template in the Body of my API Gateway before but unable to solve the invalid authorizer issue.
I've figured out the issue. There are 2 main things:
The IntegrationHttpMethod for Lambda must be POST. I found the answer here.
The template didn't have AWS::Lambda::Permission that allows API Gateway to invoke Lambda function.
With the template, when you use AWS::Lambda::Permission, it will show the API as a trigger of your Lambda function.
However, if you manually create the API Gateway and link it with your Lambda function, it won't show API Gateway as a trigger but it still works.
So for the template I posted above, I needed to add these for it to work:
"LambdaPermission": {
"Type": "AWS::Lambda::Permission",
"Description": "Permission for API GateWay to invoke Lambda.",
"Properties": {
"Action": "lambda:invokeFunction",
"FunctionName": {
"Fn::GetAtt": [
"LambdaFunction",
"Arn"
]
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Join": [
"",
[
"arn:aws:execute-api:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":",
{
"Ref": "ApiGateway"
},
"/*"
]
]
}
}
},
And edit method ANY to look like this
"methodNotesANY": {
"Type": "AWS::ApiGateway::Method",
"DependsOn": "LambdaPermission",
"Properties": {
"AuthorizationType": "COGNITO_USER_POOLS",
"AuthorizerId": {
"Ref": "GatewayAuthorizer"
},
"RestApiId": {
"Ref": "ApiGateway"
},
"ResourceId": {
"Ref": "resourceNotes"
},
"HttpMethod": "ANY",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
},
"IntegrationResponses": [{
"StatusCode": "200"
}]
},
"MethodResponses": [{
"ResponseModels": {
"application/json": "Empty"
},
"StatusCode": "200"
}]
}
},
My Best Guess: The POST to your ANY lambda function is failing during execution, and not setting the Access-Control-Allow-Origin header to * (or your domain). Anytime I get a 5XX error and a CORS error at the same time from a non-OPTIONS request, this is almost always the case for me.
Recommended Next Steps: Reproduce the error situation after adding debug logging to your Lambda source code, and turning on CloudWatch Logs in your API Gateway Rest API. You can do this by going to the API Gateway console, clicking on Stages > Prod > Logs/Tracing, then checking these two: Enable CloudWatch Logs (Log level: INFO), and Enable Detailed CloudWatch Metrics. Then you must "deploy" the changes in order for them to take effect. Do this by clicking the Actions button from your Rest API's Resources menu, and choosing Deploy API. I also recommend logging the extendedRequestId (an event property passed to your handler) from your Lambda function in order to tie the Lambda request to the API Gateway request: event.requestContext.extendedRequestId.
Example API Gateway logs:
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Extended Request Id: b5zpBGS3IAMFvqw=
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Verifying Usage Plan for request: b66b3876-984b-11e9-95eb-dd93c7e40ca0. API Key: API Stage: 1234567890/Prod
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) API Key authorized because method 'ANY /forms' does not require API Key. Request will not contribute to throttle or quota limits
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Usage Plan check succeeded for API Key and API Stage 1234567890/Prod
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Starting execution for request: b66b3876-984b-11e9-95eb-dd93c7e40ca0
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) HTTP Method: GET, Resource Path: /forms
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Lambda execution failed with status 200 due to customer function error: select count(*) AS `count(*)` from (select `user`.* from `user` where (id IN ('some_id_123'))) as `temp` - Cannot enqueue Query after fatal error.. Lambda request id: 1ae2bb06-5347-4775-9277-caccc42f18f2
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Method completed with status: 502
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) AWS Integration Endpoint RequestId : 1ae2bb06-5347-4775-9277-caccc42f18f2
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) X-ray Tracing ID : 1-5d13cca0-3be96a1ab93a877edc70577c
Example correlated Lambda execution logs:
START RequestId: 1ae2bb06-5347-4775-9277-caccc42f18f2 Version: $LATEST
2019-06-26T19:50:56.391Z 1ae2bb06-5347-4775-9277-caccc42f18f2 { "extendedRequestId": "b5zpBGS3IAMFvqw=", ... }
2019-06-26T19:50:57.853Z 1ae2bb06-5347-4775-9277-caccc42f18f2 { "errorMessage": "select count(*) AS `count(*)` from (select `user`.* from `user` where (id IN ('some_id_123'))) as `temp` - Cannot enqueue Query after fatal error.", ... }
END RequestId: 1ae2bb06-5347-4775-9277-caccc42f18f2
REPORT RequestId: 1ae2bb06-5347-4775-9277-caccc42f18f2 Duration: 1660.45 ms Billed Duration: 1700 ms Memory Size: 256 MB Max Memory Used: 57 MB
Other Thoughts: Export the Swagger definitions of both the broken API and the working API. Compare and see what is different. Do this from the console by going to Stages > Prod > Export > Export as Swagger + API Gateway Extensions. It may not be exactly the same as the CloudFormation template, but it's pretty close.
At the time of this post, Lambda Proxy Integration (AWS_PROXY) and CORS (Access-Control-Allow-Origin) don't work very well together. My approach -inspired on this explanation- was to use AWS instead of AWS_PROXY and manually provide Mapping templates for both request and response as follows:
MyApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Stage
Cors:
AllowMethods: "'POST,OPTIONS'"
AllowHeaders: "'Access-Control-Allow-Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with,x-requested-for'"
AllowOrigin: "'*'"
DefinitionBody:
swagger: 2.0
info:
version: 1.1
title: !Ref AWS::StackName
paths:
/mypath:
get:
responses:
"200":
schema:
$ref: "#/definitions/Empty"
headers:
Access-Control-Allow-Origin:
type: string
x-amazon-apigateway-integration:
httpMethod: POST # must be POST even for GET
type: AWS # must be AWS to allow cors headers
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambda.Arn}/invocations
requestTemplates:
application/json: |
{
#set($params = $input.params().querystring)
"queryStringParameters" : {
#foreach($param in $params.keySet())
"$param" : "$util.escapeJavaScript($params.get($param))" #if($foreach.hasNext),#end
#end
},
#set($params = $input.params().path)
"pathParameters" : {
#foreach($param in $params.keySet())
"$param" : "$util.escapeJavaScript($params.get($param))" #if($foreach.hasNext),#end
#end
}
}
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
responseTemplates:
application/json: |
#set($payload = $util.parseJson($input.json('$')))
#set($context.responseOverride.status = $payload.statusCode)
$payload.body

Ansible uri call with Django JWT token

I would like to call django server with ansible:
I have called:
- name: Check status 200
uri:
url: https://{{ rest_server }}/api/users/api-token-auth/
method: POST
headers:
Content-Type: "application/json"
body: '{"username": "username", "password": "password"}'
return_content: yes
register: token
and I get the token. Now I would like to use this token for the next call, but I can't figure out how this is working....
I try
- name: Check that LOGIN returns a status 200
uri:
url: https://{{ rest_server }}/api/users/auth/
method: POST
headers:
Content-Type: "application/json"
Authorization: "JWT {{ token.content[token] }}"
body: '{"username": "user", "password": "pass"}'
return_content: yes
register: webpage
but I get error:
"msg": "The task includes an option with an undefined variable. The error was: ansible.utils.unsafe_proxy.AnsibleUnsafeText object has no element {u'cookies': {}, u'vary': u'Accept', u'access_control_allow_headers': u'Access-Control-Allow-Origin, Content-Type, X-CSRFToken, Authorization, Access-Bw, Content-Disposition', u'access_control_allow_methods': u'GET, DELETE, POST, PUT, OPTIONS', u'access_control_allow_credentials': u'true', u'content': u'{\"token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im1hcmtvLnphZHJhdmVjQHJlc3VsdC5zaSIsImV4cCI6MTUxNTAxNDE1OSwidXNlcl9pZCI6NCwidXNlcm5hbWUiOiJtYXJrby56YWRyYXZlY0ByZXN1bHQuc2kifQ.otlXbiuXnDJPiLrEKdMTKBgBMbvIGApBVH_aPI5mSd4\"}', 'failed': False, u'json': {u'token': u'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im1hcmtvLnphZHJhdmVjQHJlc3VsdC5zaSIsImV4cCI6MTUxNTAxNDE1OSwidXNlcl9pZCI6NCwidXNlcm5hbWUiOiJtYXJrby56YWRyYXZlY0ByZXN1bHQuc2kifQ.otlXbiuXnDJPiLrEKdMTKBgBMbvIGApBVH_aPI5mSd4'},....
What is the right way to do it?
uri module returns content as string.
Use {{ (token.content | from_json).token }} or {{ token.json.token }}.