Reputation: 1832
Is there a way to "safely" store a bearer token in cookies (server side from an Express server running a Next.js app) and then provide it as part of the header so that it's included with every Apollo request? The Apollo team has an example using localStorage, but nothing about grabbing it from a cookie vs localStorage to set in the header. I'm looking into this in order to mitigate XSS. Is there a way to safely provide a token to this code without exposing the token in the browser? This has seemingly been covered in parts in multiple tutorials, but I can't seem to find any definitive code based on this example.
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()
});
I have an Oauth2 server that is expecting a bearer token sent from the header in the form of authorization: 'Bearer ****'. I'm just looking for the most secure way to do this, and feel like im getting conflicting information from the majority of tutorials.
Upvotes: 1
Views: 1159
Reputation: 707326
Making my comments into an answer since it helped you figure things out:
Browser Javascript cannot access a server-only cookie at all. So, if the server is putting the token in a server-only cookie, then you can't access that from browser Javascript. The server could make it just a regular cookie and then you could get to it from browser Javascript. Or, if the client isn't actually in a browser, it could get the cookie.
Is there a way to safely provide a token to this code without exposing the token in the browser?.
If this code is in a browser (which it looks like it is because it's accessing localStorage), then "no", there is no way to let this code have access to the token, but not let other code in the browser have access to it. Anything you access with browser Javascript is accessible to the world. Usually, you maintain security by having your server keep track of auth tokens and having your server access the privileged server on behalf of the client and just send results to the client.
What I'm asking is. Is there a way to attach the token cookie via node.js so that it gets attached to all Apollo requests without adding it via the client.
Are Apollo requests being made direct from the client or only from your server? Sorry, but I don't understand your architecture here. If only from the server, then you can create a client session on the server (see express-session) and you can store things on the server in that session that belong to a specific client and you can then retrieve those things on future requests.
Upvotes: 1