honkskillet
honkskillet

Reputation: 3137

Add JWT to all GraphQL/AppSynce requests when logged in with AWS Amplify

I have an AppSync app that uses IAM auth (connect to Cognito User and Identity pools). When using IAM auth, the $event.context.identity is a Cognito Identity Pool object that doesn't have the user's info (no username, sub, email, etc.)

I believe that I need to pass the UserPoolID JWT (which is available in the client side via Amplify) to AppSync whenever I make a graphQL request. But I haven't been able to figure out how to add JWT to (presumably) the header.
-------------EDIT-------------- AppSyncClient is the client (built on apollo). The App.js looks like

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import appSyncConfig from "./AppSync";
import { ApolloProvider } from "react-apollo";
import AWSAppSyncClient from "aws-appsync";
import { Rehydrated } from "aws-appsync-react";
import { Auth } from 'aws-amplify'
import AWS from'aws-sdk';

import AllPosts from './Components/AllPosts';
// more routes

const Home = () => (
  <div > <AllPosts /> </div>
);

const App = () => (
  <div> <Router> <div> 
        <Route exact={true} path="/" component={Home} /> 
        //more routes
   </div> </Router> </div>
);

const client = new AWSAppSyncClient({
  url: appSyncConfig.graphqlEndpoint,
  region: appSyncConfig.region,  
  auth: {
    type: appSyncConfig.authenticationType,  //AWS_IAM
    apiKey: appSyncConfig.apiKey,  
    credentials: () => Auth.currentCredentials(),
});

const WithProvider = () => (
  <ApolloProvider client={client}>
    <Rehydrated>
      <App />
    </Rehydrated>
  </ApolloProvider>
);

export default WithProvider;

Upvotes: 3

Views: 1915

Answers (1)

RozenMD
RozenMD

Reputation: 344

Assuming your GraphQL client is Apollo, the key is to use setContext as your authLink from the apollo-link-context library.

Example:

import ApolloClient from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import { setContext } from 'apollo-link-context';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { withClientState } from 'apollo-link-state';
import { clientState } from './clientState';
import { Auth } from 'aws-amplify';

const cache = new InMemoryCache();

//TODO:  need to cache token
const authLink = setContext((request) => new Promise( (resolve, reject) => {
  Auth.currentSession()
  .then(session => {
    const token = session.idToken.jwtToken;
    resolve({
      headers: { Authorization: token }
    });
  })
}));

const stateLink = withClientState({ ...clientState, cache });

const client = new ApolloClient({
  cache,
  link: ApolloLink.from([
    authLink,
    stateLink, //near end but before HttpLink
    new HttpLink({uri: process.env.REACT_APP_GRAPHQL_ENDPOINT })
  ])
});

export default client;

(Code from: https://github.com/aws/aws-amplify/issues/434#issuecomment-372349010)

Upvotes: 2

Related Questions