3

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

enter image description here

And here how it's set when I log out...

enter image description here

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.

netnull
  • 201
  • 1
  • 3
  • 13

1 Answers1

3

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");

mo3n
  • 1,522
  • 2
  • 10
  • 34