Response not sucessful:Recevied status code 500 using apolloclient graphql reactNative - react-native

when put token value as hardcoded it's work properly,but when i got token from asyncstorage and pass token in headers i got this error
Response not sucessful:Recevied status code 500 What is wrong in mycode?
import { ApolloClient,ApolloProvider,InMemoryCache,gql } from '#apollo/client'
import { createUploadLink } from 'apollo-upload-client'
const getToken = async () => {
const token = await AsyncStorage.getItem('#storage_Key')
return token
}
const token = getToken()
const client = new ApolloClient({
link: createUploadLink({
uri: 'http://192.168.1.82:8080/graphql',
headers: {
authorization: token
}
}),
cache: new InMemoryCache()
})
When I add authorizan in headers I got this Error:Response not sucessful:Received status code 500 In React native otherwise it's work perfectly . What is issue here?

Can you try then function for async function
getToken().then((token) => {
const client = new ApolloClient({
link: createUploadLink({
uri: 'http://192.168.1.82:8080/graphql',
headers: {
authorization: token
}
}),
cache: new InMemoryCache()
});
});

Related

Constructing ApolloClient for Authorization

I’m trying to set an authorization middleware yo my Apollo Client but something is not working. I can set the corresponding header correctly but my server still responds as i’m not authenticated.
Tried this:
const httpLink = new HttpLink({
uri: process.env.API_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 apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
includeUnusedVariables: true,
credentials: "include",
connectToDevTools: true,
cache: new InMemoryCache({})
And this:
const httpLink = new HttpLink({
uri: process.env.API_GRAPHQL,
});
const authMiddleware = new ApolloLink((operation, forward) => {
var token = localStorage.getItem("token");
operation.setContext({
headers: {
Authorization: token ? `Bearer ${token}` : "",
},
});
console.log(operation);
return forward(operation);
});
const apolloClient = new ApolloClient({
link: authMiddleware.concat(httpLink),
includeUnusedVariables: true,
credentials: "include",
connectToDevTools: true,
cache: new InMemoryCache({})
I’ve also tried with createHttpLink instead of new httpLink, and with concat(middleware, httpLink) instead of middleware.concat(httpLink).
The sent request has correctly set the token, but the response is still an auth error.
If i do not set any middleware and hard-code my token the Client works fine, something in the construction of my link is not working…
Is there something i’m missing? what are my possibilities? Is there a way I can debug my client?
Thank’s in advance.

Next.js: React Apollo Client Not sending cookies?

I'm using Apollo Client as a graphql client on my next.js application, Here is the function that creates a client for me:
let client: ApolloClient<any>;
export const __ssrMode__: boolean = typeof window === "undefined";
export const uri: string = "http://localhost:3001/graphql";
const createApolloClient = (): ApolloClient<any> => {
return new ApolloClient({
credentials: "include",
ssrMode: __ssrMode__,
link: createHttpLink({
uri,
credentials: "include",
}),
cache: new InMemoryCache(),
});
};
Surprisingly, when I make a mutation to the graphql server I'm able to set the cookies but, I'm not able to get the cookies from the client. What may be possibily the problem?
I came to the same problem, my solution was to create a client every time a server-side rendering is made, maybe it's not ideal to have a client to execute GraphQL calls in the browser and others in the server but it's what worked best for me. This is the code:
import { ApolloClient, createHttpLink, InMemoryCache } from '#apollo/client';
import { NextPageContext } from 'next';
import { setContext } from '#apollo/client/link/context';
export const httpLink = createHttpLink({
uri: 'http://localhost:4000/graphql',
credentials: 'include',
});
const CreateClient = (ctx: NextPageContext | null) => {
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
cookie:
(typeof window === 'undefined'
? ctx?.req?.headers.cookie || undefined
: undefined) || '',
},
};
});
return new ApolloClient({
credentials: 'include',
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
ssrMode: true,
});
};
export default CreateClient;
So, what I do is pass the context from the getServerSideProps and see if I have some cookies there, if so I just set the cookies, you can also send the authorization token if it's in the cookie. To call it is very simple:
export async function getServerSideProps(context: NextPageContext) {
const client = CreateClient(context);
const { data } = await client.query({
query: SOME_QUERY,
});
return {
props: {
data,
},
};
}
You can also do a HOC as in the Ben Awad tutorial Apollo Client HOC but I think it was too much for what I was trying to do. Hope it helped you or helps someone there :)
Also, I'm using Next 12.1.5 and React 18

Vue apollo - send authorization over websockets

I have a vue web app from which I'm trying to run a subscription using a hasura query.
My problem is that I cannot pass to the Websocket request an authorization token as the backend expects.
These are my current settings:
const token = localStorage.getItem("token") || null;
const options = {
httpUri: //graphql http entpoint,
wsUri: //graphql ws endpoint
};
let link = new HttpLink({
uri: options.httpUri
});
// Create the subscription websocket link if available
if (options.wsUri) {
const wsLink = new WebSocketLink(
new SubscriptionClient(options.wsUri, {
lazy: true,
reconnect: true,
connectionParams: {
headers: {
Authorization: `Bearer ${token}`
}
}
})
);
// using the ability to split links, you can send data to each link
// depending on what kind of operation is being sent
link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === "OperationDefinition" &&
definition.operation === "subscription"
);
},
wsLink,
link
);
}
const authLink = setContext((_, { headers }) => {
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : ""
}
};
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message }) => {
if (message.includes("unauthorized")) {
EventBus.$emit("unauthorized");
}
});
if (networkError) console.log(`[Network error]: ${networkError}`);
});
const apolloClient = new ApolloClient({
link: ApolloLink.from([errorLink, authLink, link]),
cache: new InMemoryCache(),
connectToDevTools: true
});
const apolloProvider = new VueApollo({
defaultClient: apolloClient
});
When I try to run the subscription I get
HTTP Authentication failed; no valid credentials available
And in the ws request header I cannot see my Authorization bearer set.
A side info I need authorization for both http and ws requests
I think errorLink or authLink unexpectedly change websocket header token. You try modifying a bit:
const httpLink = from([
authLink,
// errorLink,
new HttpLink({
uri: Config.httpDataHost,
headers: {
[XHasuraClientName]: Config.hasuraClientName
}
})
]);
const wsLink = new WebSocketLink({ ... });
const link = ...
const apolloClient = new ApolloClient({
link: ApolloLink.from([errorLink, link]),
cache: new InMemoryCache(),
connectToDevTools: true
});
If it doesn't work, you can try commenting errorLink to check. Another thing is, you shouldn't get token globally, but use lazy function so ApolloClient can always get latest access token from local storage
const getIdToken = () => localStorage.getItem('token') || null;
const wsLink = new WebSocketLink({
uri: options.wsUri,
options: {
connectionParams: () => ({
headers: {
Authorization: getIdToken(),
}
}),
...
}
});
PS: I have an example repository with React + Apollo Client 3.0. Although you are using Vue.js,Apollo Client construction is the same https://github.com/hgiasac/ra-hasura-typescript-boilerplate/blob/auth-jwt/src/shared/ApolloClient.ts

Why there is no data after the first login?

Dear vue and apollo users;
I am dealing with the first time install problem.
When I first launch the app, I don't get results.
I am using ApolloClient, InMemoryCache, HttpLink from "apollo-boost"
I store my userID and JWT in ApplicationSettings(local storage)
How to set token dynamically?
Vue.use(VueApollo);
const httpLink = new HttpLink({
uri: "https://sebapi.com/graphql"
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from ApplicationSettings if it exists
var tokenInAppSettings = ApplicationSettings.getString("token");
// return the headers to the context so HTTP link can read them
return {
headers: {
...headers,
authorization: tokenInAppSettings
? `Bearer ${tokenInAppSettings}`
: null
}
};
});
export const apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
const apolloProvider = new VueApollo({
defaultClient: apolloClient
});
I have created a GitHub repo reproducing problem
and a youtube video of the problem
There is no error during login but after navigating to the list page for the first time I got following errors...
JS: [Vue warn]: Invalid prop: type check failed for prop "items". Expected Array, Object, got Undefined
JS: Error sending the query 'birds' ServerError: Response not successful: Received status code 400
IT SEEMS APOLLO DOES NOT HAVE userID during first query.
NOTE: You can easily clear user data by using yarn cl script
# debug app without HMR
yarn devn
# clear user data of app
yarn cl
Solution repo using vuex:
https://github.com/kaanguru/data-firstlogin/tree/user-in-vuex
Move userID into vue instance
+welcome.vue+
//const userId = ApplicationSettings.getNumber("userID");
// I have moved userID into vue.
export default {
data() {
return {
birds:[],
bird:{
id: null,
isim: "",
bilezik: ""
},
userId: ApplicationSettings.getNumber("userID")
};
},
apollo: {
birds: {
query: gql`
query myBirds($userId: ID!) {
birds(where: { user: $userId }) {
id
isim
bilezik
}
}
`,
variables() {
return {
userId: this.userId,
};
},
},
},
};

How to pass Additional Header when calling mutation in React native apollo client?

How to pass Additional Header when calling mutation in React native apollo client ?
my Client is here:
import { HttpLink } from 'apollo-link-http';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
const makeApolloClient = (token) => {
// create an apollo link instance, a network interface for apollo client
const link = new HttpLink({
uri: 'http://x.x.x.x:xxxx/xxxx',
headers: {
Authorization: `Bearer ${token}`
},
});
// create an inmemory cache instance for caching graphql data
const cache = new InMemoryCache();
// instantiate apollo client with apollo link instance and cache instance
const client = new ApolloClient({
link,
cache
});
return client;
};
export default makeApolloClient;
If i need to add additional header to this same client when using query or mutation how can i do it ?
Is it possible with "apollo-link-context" ?
You haven't specified your React version however assuming you use Hooks you do it as follows. If you aren’t using hooks change the doc version for the links at the bottom of this answer using the drop down in the top left.
Where you have your query:
const GET_USER = gql`
query getUser{
node {
name
age
}
}
`;
You’ll want to run a query with the useQuery hook:
const { loading, error, data } = useQuery(GET_USER, {
context: {
headers: {
"Content-Type": "application/json"
}
}
})
Docs:
You can find the docs for each here:
- UseQuery: https://www.apollographql.com/docs/react/essentials/queries/
- Context Headers: https://www.apollographql.com/docs/link/links/http/#passing-context-per-query
This can be done by receiving the context which is set in mutation/query.
Setting Custom header in mutation
const [addTodo] = useMutation(ADD_TODO, {
refetchQueries: [{ query: GET_TODO }], //updating the list of todos list after adding
context: {
headers: {
"x-custom-component-add": "kkk-add",
"x-origin-server": "pure-react"
}
}
});
receiving context in middle ware which set in mutation/query
const httpLink = new HttpLink({ uri: "https://sxewr.sse.codesandbox.io/" });
const authMiddleware = new ApolloLink((operation, forward) => {
const customHeaders = operation.getContext().hasOwnProperty("headers") ? operation.getContext().headers : {};
console.log(customHeaders);
operation.setContext({
headers: {
...customHeaders
//we can also set the authorization header
// authorization: localStorage.getItem('jjjjjj'),
}
});
return forward(operation);
});
Finally passing the middleware in Apoolo Client
const client = new ApolloClient({
cache: new InMemoryCache(),
link: from([authMiddleware, httpLink])
});
Here is the working sample.
https://codesandbox.io/s/passing-custom-header-in-graphql-mutation-query-l332g?file=/src/index.js
Custom header look like this