Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

json: cannot unmarshal string into Go struct field APIGatewayProxyRequestContext.authorizer #154

Closed
Yenchu opened this issue Jan 4, 2019 · 5 comments · Fixed by #159
Closed

Comments

@Yenchu
Copy link

Yenchu commented Jan 4, 2019

When integrating with api gateway WebSocket API, got error in CloudWatch log:
json: cannot unmarshal string into Go struct field APIGatewayProxyRequestContext.authorizer of type map[string]interface {}: UnmarshalTypeError null

To log requestContext info, the field authorizer is empty:
requestContext:map[stage:... authorizer: messageId:<nil>...

@piotrkubisa
Copy link
Contributor

piotrkubisa commented Jan 4, 2019

The type definition is a bit different for a Websocket events - for an instance (I might don't recall correctly) there are at least two fields which are missing in the requestContext:

connectionId: string
connectedAt: number

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-logging.html

That said, aws-lambda-go repository lacks of struct for an API Gateway usage with a websocket. It would be great if someone could copy and paste the raw event payload here or make an PR and add it into the test data directory and create new struct with a corresponding json tags definition.

@Dasio
Copy link

Dasio commented Jan 7, 2019

Here is raw event payload

{
    "headers": {
        "Host": "*.execute-api.eu-central-1.amazonaws.com",
        "Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits",
        "Sec-WebSocket-Key": "*",
        "Sec-WebSocket-Version": "13",
        "X-Amzn-Trace-Id": "*",
        "X-Forwarded-For": "*.*.*.*",
        "X-Forwarded-Port": "443",
        "X-Forwarded-Proto": "https"
    },
    "isBase64Encoded": false,
    "multiValueHeaders": {
        "Host": [
            "*.execute-api.eu-central-1.amazonaws.com"
        ],
        "Sec-WebSocket-Extensions": [
            "permessage-deflate; client_max_window_bits"
        ],
        "Sec-WebSocket-Key": [
            "*"
        ],
        "Sec-WebSocket-Version": [
            "13"
        ],
        "X-Amzn-Trace-Id": [
            "Root=*"
        ],
        "X-Forwarded-For": [
            "*.*.*.*"
        ],
        "X-Forwarded-Port": [
            "443"
        ],
        "X-Forwarded-Proto": [
            "https"
        ]
    },
    "requestContext": {
        "apiId": "*",
        "authorizer": "",
        "connectedAt": "*",
        "connectionId": "*",
        "domainName": "*.execute-api.eu-central-1.amazonaws.com",
        "error": "",
        "eventType": "CONNECT",
        "extendedRequestId": "*",
        "identity": {
            "accessKey": null,
            "accountId": null,
            "caller": null,
            "cognitoAuthenticationProvider": null,
            "cognitoAuthenticationType": null,
            "cognitoIdentityId": null,
            "cognitoIdentityPoolId": null,
            "sourceIp": "*.*.*.*",
            "user": null,
            "userAgent": null,
            "userArn": null
        },
        "integrationLatency": "",
        "messageDirection": "IN",
        "messageId": null,
        "requestId": "*",
        "requestTime": "07/Jan/2019:09:20:57 +0000",
        "requestTimeEpoch": 1546852857724,
        "routeKey": "$connect",
        "stage": "test",
        "status": ""
    }
}

@Dasio
Copy link

Dasio commented Jan 7, 2019

These are extra fields in APIGatewayProxyRequestContext

	ConnectedAt        int64       `json:"connectedAt"`
	ConnectionID       string      `json:"connectionId"`
	DomainName         string      `json:"domainName"`
	Error              string      `json:"error"`
	EventType          string      `json:"eventType"`
	ExtendedRequestId  string      `json:"extendedRequestId"`
	IntegrationLatency string      `json:"integrationLatency"`
	MessageDirection   string      `json:"messageDirection"`
	// IDK type of this
	MessageID          interface{} `json:"messageId"`
	RequestTime        string      `json:"requestTime"`
	RequestTimeEpoch   int64       `json:"requestTime"`
	RouteKey           string      `json:"routeKey"`
	Status             string      `json:"status"`

But in WS event it is

	Authorizer   string                      `json:"authorizer"`

Now it's

	Authorizer   map[string]interface{}    `json:"authorizer"`

codemedic added a commit to codemedic/aws-lambda-go that referenced this issue Jan 24, 2019
@jozanza
Copy link

jozanza commented Feb 8, 2019

Just chiming in here -- I forked and deployed to aws with the code from #159, and it seems that if you do not set an authorizer on your WebSocket route in API Gateway, the marshalling of APIGatewayWebsocketProxyRequest will still fail since it's not able to convert null to map[string]interface{}. Entirely removing the Authorizer field from the struct worked, but that's probably not the best option 😅 .

@bmoffatt
Copy link
Collaborator

Authorizer is going to have to be an interface{} to be compatible with all the different ways it can be populated

bmoffatt pushed a commit that referenced this issue Feb 20, 2019
* apigw websocket event testdata

* Add event for ApiGW Websocket integration

* typo in struct name

* fixed test event

* matching apigw testdata

* duplicated identidy data

* duplicated json field requestTimeEpoch

* fixed test request json order

* Fixes suggestions from pr: #159

issue: #154

* ExtendedRequestId -> ExtendedRequestID

* Change type of Authorizer to interface{}

* Update apigw.go

changed wrong `Authorizer`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants