I've build my app with Vite. I read many documents on web about the topic but I'm still very confused. I've a login form that send credentials to a protected view. When post the data I set the headers and store the Bearer token in the local storage. The problem is that it doesn't work cause the Bearer token result equal to null. Only when I logout the token is set in the headers.
That's how is the header when I log in
And here how it's set when I log out...
My main.js code is this:
import { createApp, provide, h } from "vue";
import {
ApolloClient,
createHttpLink,
InMemoryCache,
} from "@apollo/client/core";
import { DefaultApolloClient } from "@vue/apollo-composable";
import App from "./App.vue";
import router from "./router";
import { createPinia } from "pinia";
import { provideApolloClient } from "@vue/apollo-composable";
const authToken = localStorage.getItem("auth-token");
const httpLink = createHttpLink({
uri: "http://localhost/graphql",
headers: {
Authorization: "Bearer " + authToken,
},
});
const cache = new InMemoryCache();
const apolloClient = new ApolloClient({
link: httpLink,
cache,
});
provideApolloClient(apolloClient);
const app = createApp({
setup() {
provide(DefaultApolloClient, apolloClient);
},
render: () => h(App),
});
app
.use(router)
.use(createPinia())
.mount("#app");
and this is my routes.js
const router = createRouter({
history: createWebHistory(),
routes
})
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const isAuthenticated = localStorage.getItem('auth-token');
if(requiresAuth && isAuthenticated===null){
next('/auth/login');
}else {
next();
}
});
I'm surely making some mistakes in my main.js but I cannot understand what's wrong. I'm very confused :-/ Thanks to who'll be able to help me.
Try using a helper function to get the token from local storage; I'm using this method and it's working fine for me. To get your code more organized, create a separate folder to define the apollo client. Here is the code:
// apolloClient.ts
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client/core";
function getHeaders() {
const headers: { Authorization?: string; "Content-Type"?: string } = {};
const token = localStorage.getItem("access-token");
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
headers["Content-Type"] = "application/json";
return headers;
}
// Create an http link:
const httpLink = new HttpLink({
uri: `${import.meta.env.VITE_API_URL}/graphql`,
fetch: (uri: RequestInfo, options: RequestInit) => {
options.headers = getHeaders();
return fetch(uri, options);
},
});
// Create the apollo client
export const apolloClient = new ApolloClient({
cache: new InMemoryCache(),
link: httpLink,
defaultOptions: {
query: {
errorPolicy: "all",
},
mutate: {
errorPolicy: "all",
},
},
});
Then you can use it in your main.ts like this:
// main.ts
import { createApp, h } from "vue";
import { provideApolloClient } from "@vue/apollo-composable";
import App from "./App.vue";
import { apolloClient } from "./apolloClient";
const app = createApp({
setup() {
provideApolloClient(apolloClient);
},
render: () => h(App),
});
app.mount("#app");