|
import {ApolloLink} from "apollo-link"; |
|
import {ApolloClient} from "apollo-client"; |
|
import {createHttpLink} from 'apollo-link-http'; |
|
import {HttpLink} from "apollo-link-http"; |
|
import {InMemoryCache} from "apollo-cache-inmemory"; |
|
|
|
|
|
const customFetch = (uri, options) => { |
|
|
|
// set a reference to the refresh promise |
|
this.refreshingPromise = null; |
|
|
|
// run the initial request |
|
let initialRequest = fetch(uri, options); |
|
|
|
// return the initial requests promise |
|
return initialRequest.then((response) => { |
|
return (response); |
|
}).then((json) => { |
|
|
|
// check if we have a none empty json |
|
// and if we have 403 error (Forbidden) |
|
if (json && json.status === 403) { |
|
|
|
// if we don't already have have promising |
|
// create one that refreshes the token |
|
if (!this.refreshingPromise) { |
|
// attach logic to get refresh token that returns a promise |
|
// something like: |
|
// this.refreshingPromise = fetch('/o/token/', { method: 'POST' }) |
|
// .then((refresh_token) => { |
|
// return refresh_token |
|
// }) |
|
// }) |
|
} |
|
|
|
// wait for refresh token to complete then here we can get the new token |
|
// and assigned it to `authorization` headers and re-run the same fetch |
|
return this.refreshingPromise.then((response) => { |
|
this.refreshingPromise = null; |
|
|
|
let newAccessToken = response.accessToken; |
|
|
|
options.headers.authorization = `Bearer ${newAccessToken}`; |
|
|
|
return fetch(uri, options); |
|
}).catch((errors)=>{ |
|
// otherwise error |
|
// here you can also run the logout() method |
|
// as we have now failed again. |
|
console.error(errors); |
|
return false; |
|
}) |
|
} |
|
|
|
// else if everything good |
|
// simply return the response |
|
return json; |
|
}); |
|
}; |
|
|
|
const httpLink = createHttpLink({ |
|
uri: '/graphql', |
|
fetch: customFetch, // create a custom fetch |
|
}); |
|
|
|
const authLink = new ApolloLink((operation, forward) => { |
|
// get the authentication token |
|
let accessToken = localStorage.getItem('token'); |
|
accessToken = accessToken ? `Bearer ${accessToken}` : null; |
|
|
|
operation.setContext({ |
|
headers: {authorization: accessToken} |
|
}); |
|
|
|
return forward(operation) |
|
}); |
|
|
|
const client = new ApolloClient({ |
|
link: authLink.concat(httpLink), |
|
cache: new InMemoryCache() |
|
}); |