登录验证-无法使用Apollo客户端使用JWT令牌从Nextjs连接到graphql



我是这项技术的新手。我使用Django作为后端,使用Nextjs作为前端。我正在尝试使用apollo客户端3.3.8连接JWT后端的graphql。当我尝试连接时,我得到graphql错误为";未登录";。

import { ApolloClient, useQuery, HttpLink, ApolloLink, gql, createHttpLink,from } from '@apollo/client';
import {cache} from './cache'
import { useMemo } from "react";
export const typeDefs = gql`
extend type Query {
isLoggedIn: Boolean!
}
`;

let apolloClient
function createIsomorphLink() {
if (typeof window != 'undefined') {
const { HttpLink } = require('@apollo/client/link/http')
return new HttpLink({
uri: 'http://localhost:8000/graphql/',
headers: {
authorization: localStorage.getItem('token') || null,
}
})
}
}
function createApolloClient() {
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: createIsomorphLink(),
cache: cache,
})
}
export function initializeApollo(initialState = null) {
const _apolloClient = apolloClient ?? createApolloClient()
// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// gets hydrated here
if (initialState) {
_apolloClient.cache.restore(initialState)
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient
return _apolloClient
}
export function useApollo(initialState) {
const store = useMemo(() => initializeApollo(initialState), [initialState])
return store
}

如果您从localStorage获取JWT,那么我建议在将其传递到auth标头之前先检索它。也许创建一个全局可重用的变量,从localStorage读取JWT,这是它唯一的工作。或者,尝试使用authLink并将httpLink连接到authLink。请参阅下面我的apollo.ts的内容:

import { useMemo } from 'react';
import {
ApolloClient,
InMemoryCache,
NormalizedCacheObject,
ApolloLink,
HttpLink
} from '@apollo/client';
import fetch from 'isomorphic-unfetch';
import { IncomingHttpHeaders } from 'http';
import { setContext } from '@apollo/client/link/context';
import { onError } from '@apollo/client/link/error';
// import merge from 'deepmerge';
import { AppInitialProps, AppProps } from 'next/app';
// import { CookiesStatic } from 'js-cookie';
// import isEqual from 'lodash/isEqual';
export const APOLLO_STATE_PROP_NAME = '__APOLLO_STATE__';
let apolloClient:
| ApolloClient<NormalizedCacheObject>
| undefined;
const wpRefresh = process.env.WORDPRESS_AUTH_REFRESH_TOKEN!;
const oneEndpoint = process.env.NEXT_PUBLIC_ONEGRAPH_API_URL!;
function createApolloClient(
headers: IncomingHttpHeaders | null = null
): ApolloClient<NormalizedCacheObject> {
// const token = session?.jwt?.toString() ?? '';
// const token =
//  getAccessToken(options) ?? getAccessTokenAsCookie(options);
const authLink: ApolloLink = setContext(
(_, { ...headers }: Headers) => {
let token: any;
// you can getToken(token) etc. here
if (!token) {
return {};
}
return {
headers: {
...headers,
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json; charset=utf-8',
Auth: `Bearer ${wpRefresh}`,
'x-jwt-auth': token ? `Bearer ${token}` : ''
},
credentials: 'include',
...(typeof window !== undefined && { fetch })
};
}
);
const errorLink: ApolloLink = onError(
({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
);
if (networkError)
console.log(
`[Network error]: ${networkError}. Backend is unreachable. Is it running?`
);
}
);
const httpLink = new HttpLink({
uri: `${oneEndpoint}`
});
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: authLink.concat(httpLink) ?? errorLink,
connectToDevTools: true,
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
// merge?: boolean | FieldMergeFunction<TExisting, TIncoming> | undefined;
wordpress: {
merge(existing, incoming, { mergeObjects }) {
// Invoking nested merge functions
return mergeObjects(existing, incoming);
}
},
google: {
merge(existing, incoming, { mergeObjects }) {
// Invoking nested merge functions
return mergeObjects(existing, incoming);
}
}
}
}
}
})
});
}
type InitialState = NormalizedCacheObject | any;
type IInitializeApollo = {
headers?: null | NodeJS.Dict<string | string[]>;
initialState?: InitialState | null;
};
export function initializeApollo(
{ headers, initialState }: IInitializeApollo = {
headers: null,
initialState: null
}
) {
// you can pass your JWT token in here 
const _apolloClient =
apolloClient ?? headers
? createApolloClient(headers)
: createApolloClient();
if (initialState) {
// Get existing cache, loaded during client side data fetching
const existingCache = _apolloClient.extract();
// Merge the existing cache into data passed from getStaticProps/getServerSideProps
const data = { ...existingCache, ...initialState };
/* This is the deepmerge method -- below */
// const data = merge(initialState, existingCache, {
//  arrayMerge: (destinationArray, sourceArray) => [
//      ...sourceArray,
//      ...destinationArray.filter(d =>
//          sourceArray.every(s => !isEqual(d, s))
//      )
//  ]
// });
// Restore the cache with the merged data
_apolloClient.cache.restore(data);
}
// for SSG and SSR ALWAYS create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient;
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient;
return _apolloClient;
}
export function addApolloState(
client: ApolloClient<NormalizedCacheObject> | any,
pageProps: (AppInitialProps | AppProps)['pageProps'] | any
) {
if (pageProps?.props) {
pageProps.props[
APOLLO_STATE_PROP_NAME
] = client.cache.extract();
}
return pageProps;
}
export function useApollo(
pageProps: (AppInitialProps | AppProps)['pageProps'] | any
) {
const state = pageProps[APOLLO_STATE_PROP_NAME];
const store = useMemo(
() => initializeApollo({ initialState: state }),
[state]
);
return store;
}

最新更新