-
-
Notifications
You must be signed in to change notification settings - Fork 522
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
How to set up Apollo Client 2.0, ApolloLink with subscriptions etc.. #144
Comments
Works great, however I needed to do some adjustments to authorization, in case anyone needs it, this worked for me. instead of: const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers
operation.setContext({
headers: {
authorization: localStorage.getItem(GC_AUTH_TOKEN) || null,
}
});
return forward(operation);
}) used: const token = localStorage.getItem(GC_AUTH_TOKEN) || null
const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers
operation.setContext({
headers: {
authorization: `Bearer ${token}`
}
})
return forward(operation)
}) Thanks @kjetilge !!! |
Why use localstorage instead of cookies? It won't be shared across subdomains and http/https |
Why not use websockets for everything? Why split? |
I found an issue. After set the the token, we have to refresh the web page to get authorization to work. Solved: #183 |
Just my 2c for future visitors (and those who asked the questions):
|
Hi @bjunc Can you make an example repo about this? |
Yeah, I think I can do that. I was actually planning on doing a Medium article about this setup (along with the back-end; which is in Elixir). Also worth noting, is that you can use |
I'm currently building a full demo app in the |
The solution above to set authentication headers via middleware uses apollo-link and apollo-client. Is it possible to have middlewares using apollo-boost to set custom headers dynamically for each request? |
Are there any examples of using the default out-of-the-box boilerplate with bearer tokens? As in, when using |
@hades200082 in your vue-apollo.js scaffolded out by the cli tool, there's a i.e. // Override the way the Authorization header is set
getAuth: () => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem(AUTH_TOKEN)
// return the headers to the context so httpLink can read them
if (token) {
return 'Bearer ' + token
} else {
return ''
}
} |
How to do this for the connection_terminated? I want to send a payload together |
FF to 2019: this is the new approach import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';
const httpLink = createHttpLink({
uri: '/graphql',
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem('token');
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
}); basically the change is that use of setContext, which is to my opinion cleaner. |
This is my entire apollo boot file when using subscriptions: import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { setContext } from 'apollo-link-context';
import { split } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
// You should use an absolute URL here
const options = {
httpUri: process.env.GRAPHQL_HTTP_ENDPOINT || 'http://localhost:7001/graphql',
wsUri: process.env.GRAPHQL_WS_ENDPOINT || 'ws://localhost:7001/graphql',
};
let link = new HttpLink({
uri: options.httpUri,
});
// Create the subscription websocket link if available
if (options.wsUri) {
const wsLink = new WebSocketLink({
uri: options.wsUri,
options: {
reconnect: true,
},
});
// using the ability to split links, you can send data to each link
// depending on what kind of operation is being sent
link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription';
},
wsLink,
link,
);
}
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem('authorization_token');
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
};
});
export const cache = new InMemoryCache();
// Create the apollo client instance
export default new ApolloClient({
link: authLink.concat(link),
cache,
connectToDevTools: true,
}); |
You have to restart the websocket connection. |
@Akryum how do i do that without restarting apollo instance? |
Thank you; your post nicely summarizes the issue, and one way to resolve it. In my case, I did not want to let the frontend code ever have access to the auth-token. So, I use the following approach instead:
Is the approach above safe/sound? If not (or only partially), another idea for making it safer:
Anyway, assuming it's safe/sound, I prefer it over making the auth-token accessible to the frontend js, because of this benefit:
EDIT: Looks like the approach above is already an established pattern! More info here: https://stackoverflow.com/a/4361358/2441655 |
I spent some time to figure it out, so just in case anyone wants to try:
The text was updated successfully, but these errors were encountered: