adamdaly
adamdaly

Reputation: 355

AWS AppSync Subscription fails during handshake

I'm trying to set up a graphql subscription but I'm getting the error:

Unhandled GraphQL subscription error Error: Error during subscription handshake

I'm using AWS Cognito User Pools for the authorisation.

To create the Subscription I'm using:

this.subscription = this.props.client.subscribe({ query: gql(onCreateVehicle) }).subscribe({
  next: response => {
    console.log(response.data.onCreateVehicle);
  },
  error: error => {
    console.warn(error);
  }
});

'onCreateVehicle' was automatically generated by Amplify and looks like this:

export const onCreateVehicle = `subscription OnCreateVehicle($owner: String!) {
  onCreateVehicle(owner: $owner) {
    id
    name
    events {
      items {
        id
        name
        date
        isDeleted
        owner
      }
      nextToken
    }
    sessions {
      items {
        id
        name
        isDeleted
        createdAt
        owner
      }
      nextToken
    }
    isDeleted
    owner
  }
}
`;

Request resolver:

{
    "version": "2018-05-29",
    "payload": {}
}

Response resolver:

## [Start] Determine request authentication mode **
#if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
  #set( $authMode = "userPools" )
#end
## [End] Determine request authentication mode **
## [Start] Check authMode and execute owner/group checks **
#if( $authMode == "userPools" )
  ## No Static Group Authorization Rules **


  ## [Start] Owner Authorization Checks **
  #set( $isOwnerAuthorized = false )
  ## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
  #set( $allowedOwners0 = $util.defaultIfNull($ctx.args.owner, null) )
  #set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"),
                        $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
  #if( $util.isList($allowedOwners0) )
    #foreach( $allowedOwner in $allowedOwners0 )
      #if( $allowedOwner == $identityValue )
        #set( $isOwnerAuthorized = true )
      #end
    #end
  #end
  #if( $util.isString($allowedOwners0) )
    #if( $allowedOwners0 == $identityValue )
      #set( $isOwnerAuthorized = true )
    #end
  #end
  ## [End] Owner Authorization Checks **


  ## [Start] Throw if unauthorized **
  #if( !($isStaticGroupAuthorized == true || $isOwnerAuthorized == true) )
    $util.unauthorized()
  #end
  ## [End] Throw if unauthorized **
#end
## [End] Check authMode and execute owner/group checks **

$util.toJson(null)

I know it has something to do with authorisation as it didn't throw the handshake error when I removed the @auth from the schema.graphql. Should there be something in the request resolver to handle the authorisation?

Adam

Upvotes: 4

Views: 1722

Answers (1)

adamdaly
adamdaly

Reputation: 355

I just had to pass the 'owner' value through the variables object.

subscribeToVehicles: async () => props.data.subscribeToMore({
    document: gql(onCreateVehicle),
    variables: {
        owner: (await Auth.currentSession()).getIdToken().payload.sub
    },
    ...

Upvotes: 2

Related Questions