Skip to content

Commit

Permalink
Solucionando la re-autenticación/refresco de tokens en el cliente
Browse files Browse the repository at this point in the history
  • Loading branch information
fforres committed Jun 22, 2024
1 parent ce1bd30 commit ba12c04
Showing 1 changed file with 17 additions and 78 deletions.
95 changes: 17 additions & 78 deletions src/api/ApolloWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import {
import { setContext } from "@apollo/client/link/context";
import { onError } from "@apollo/client/link/error";
import { RetryLink } from "@apollo/client/link/retry";
import cookies from "js-cookie";

import { useSetTokenRef, useTokenRef } from "../utils/supabase/AuthProvider";
import { COOKIE_NAME, supabaseClient } from "../utils/supabase/client";
import { supabaseClient } from "../utils/supabase/client";

const retryLink = new RetryLink();

Expand All @@ -22,8 +21,13 @@ const retryLink = new RetryLink();
// Importante ponerlo entre el retryLink y el httpLink
const errorPromotionLink = new ApolloLink((operation, forward) => {
return forward(operation).map((data) => {
if (data && data.errors && data.errors.length > 0) {
throw new Error("GraphQL Operational Error. Retriable");
if (
data &&
data.errors &&
data.errors.length > 0 &&
data.errors.some((error) => error.extensions?.code === "UNAUTHENTICATED")
) {
throw new Error("GraphQL Authentication Error. Retriable");
}
return data;
});
Expand Down Expand Up @@ -52,6 +56,8 @@ const useAuthLink = () => {
});
};

// Este link se encarga de manejar errores de autenticación
// Si el servidor responde con un code UNAUTHENTICATED, intenta refrescar el token.
const useErrorLink = () => {
const setToken = useSetTokenRef();
return onError(({ graphQLErrors, networkError, operation, forward }) => {
Expand Down Expand Up @@ -96,87 +102,20 @@ const useErrorLink = () => {
});
};

// const checkAndRefreshTokenLink = new ApolloLink((operation, forward) => {
// try {
// const undecodedToken = cookies.get(COOKIE_NAME) ?? null;
// console.log("undecodedToken", undecodedToken);
// if (!undecodedToken) {
// return forward(operation);
// }
// const token = jwtDecode(undecodedToken);
// console.log("TOKEN", token);
// if (!token || !token.exp) {
// return forward(operation);
// }
// // Refresh token if it's expired using supabaseclient (and enqueue the operation to be retried after refreshing the token)
// const now = Date.now() / 1000;
// if (token.exp - now < 60 * 5) {
// operationQueue.push(operation);
// return forward(operation);
// } else {
// return forward(operation);
// }
// } catch (error) {
// console.error("Error checking token", error);
// return forward(operation);
// }

// // if (!token) {
// // // Token does not exist, refresh it
// // supabase.auth.refreshAccessToken().then(({ data, error }) => {
// // if (error) {
// // console.error("Error refreshing access token", error);
// // observer.error(error);
// // return;
// // }

// // const newToken = data.session.access_token;
// // cookies.set(COOKIE_NAME, newToken);

// // const oldHeaders = operation.getContext().headers;
// // operation.setContext({
// // headers: {
// // ...oldHeaders,
// // authorization: `Bearer ${newToken}`,
// // },
// // });

// // forward(operation).subscribe({
// // next: (result) => observer.next(result),
// // error: (networkError) => observer.error(networkError),
// // complete: () => observer.complete(),
// // });
// // });
// // } else {
// // // Token exists, proceed with the operation
// // forward(operation).subscribe({
// // next: (result) => observer.next(result),
// // error: (networkError) => observer.error(networkError),
// // complete: () => observer.complete(),
// // });
// // }
// });
// Este link se encarga de definir donde y como se conecta el cliente de Apollo a la API
const httpLink = new HttpLink({
// Tiene que ser una URL absoluta, ya que las URLs relativas no pueden ser usadas en SSR.
uri: process.env.NEXT_PUBLIC_JSCL_API_URL,
fetchOptions: { cache: "no-store", credentials: "include" },
credentials: "include",
});

function useMakeClient() {
const httpLink = new HttpLink({
// this needs to be an absolute url, as relative urls cannot be used in SSR
uri: process.env.NEXT_PUBLIC_JSCL_API_URL,
// you can disable result caching here if you want to
// (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
fetchOptions: { cache: "no-store", credentials: "include" },
credentials: "include",
// you can override the default `fetchOptions` on a per query basis
// via the `context` property on the options passed as a second argument
// to an Apollo Client data fetching hook, e.g.:
// const { data } = useSuspenseQuery(MY_QUERY, { context: { fetchOptions: { cache: "force-cache" }}});
});
const authLink = useAuthLink();
const errorLink = useErrorLink();
return new ApolloClient({
// use the `NextSSRInMemoryCache`, not the normal `InMemoryCache`
cache: new InMemoryCache(),
link: from([
// checkAndRefreshTokenLink,
retryLink,
errorPromotionLink,
errorLink,
Expand Down

0 comments on commit ba12c04

Please sign in to comment.