I am learning GraphQL and Next.js through a Udemy Course and the author uses ApolloClient from apollo-boost package. But #apollo/client package is the new one and I started using that instead.
using apollo-boost's ApolloClient the author sets the credentials for each request like below:
new ApolloClient({
request: operation => {
operation.setContext({
fetchOptions: {
credentials: 'include'
},
headers
})
},
uri: process.env.BASE_URL,
cache: new InMemoryCache().restore(initialState || {})
})
This is not working for me as request is not present in #apollo/client's ApolloClient. So I tried like below:
const link = new HttpLink({ uri: "http://localhost:3000/graphql", credentials: 'include' });
new ApolloClient({
cache: new InMemoryCache().restore(initialState || { }),
link,
})
But the credentials are not working for each request. I am not getting user information.
I am using passport which is storing logged in user info in cookies.
Below is the index.js file for configuring passport:
const config = require('../config/dev');
const sessison = require('express-session');
const passport = require('passport');
exports.init = (server, db) => {
require('./passport').init(passport);
const sess = {
name: 'portfolio-session',
secret: config.SESSION_SECRET,
cookie: { maxAge: 2 * 60 * 60 * 100},
resave: false,
saveUninitialized: false,
store: db.initSessionStore()
}
server.use(sessison(sess));
server.use(passport.initialize());
server.use(passport.session());
}
Can somebody help with code to add authentication to ApolloClient?
Thanks :)
From the looks of it you are not actually passing the header bearing the token in your example.
Take the headers incoming from the first author's example:
[...]
fetchOptions: {
credentials: 'include'
},
headers // <- this one
})
},
[...]
Add it to the request like you were trying to do:
const link = new HttpLink({
uri: "http://localhost:3000/graphql",
headers // <-- pass it here, should contain something along these lines: { Authorization: `Bearer ${token}` } or w/e
});
const client = new ApolloClient({
cache: new InMemoryCache().restore(initialState || { }),
link,
});
Related
I'm currently working on a site wgich has a frontend consisting of next.js which communicates over graphql to a WordPress backend. the persistent queries are generated(by graphql-codegen) and are saved to a .json files both the backend and frontend can access these files.
here is the code relating to apollo and apollo codegen
codegen.js
const environment = process.env.ENV || 'development';
const url = require(`./config/${environment}`);
module.exports = {
schema: `${url.backend}/graphql`,
documents: ['./lib/queries/fragments/*.js', './lib/queries/*.js'],
generates: {
'./lib/persisted-query-ids/client.json': [
{
'graphql-codegen-persisted-query-ids': {
output: 'client',
algorithm: 'sha256',
preset: 'near-operation-file',
},
},
],
'./lib/persisted-query-ids/server.json': [
{
'graphql-codegen-persisted-query-ids': {
output: 'server',
algorithm: 'sha256',
preset: 'near-operation-file',
},
},
],
},
};
createApolloClient.js
export default function createApolloClient(initialState, ctx) {
const hashes = require('../../persisted-query-ids/client.json');
const persistedLink = createPersistedQueryLink({
useGETForHashedQueries: true, // Optional but allows better caching
// eslint-disable-next-line react-hooks/rules-of-hooks
generateHash: usePregeneratedHashes(hashes),
});
// The `ctx` (NextPageContext) will only be present on the server.
// use it to extract auth headers (ctx.req) or similar.
const fetchOptions = {
// credentials: 'include',
redirect: 'manual',
};
const fetchWithCookies = async (input, init) => {
let isomorphicFetch;
if (typeof window === 'undefined') {
isomorphicFetch = (await import('isomorphic-unfetch')).default;
} else {
isomorphicFetch = window.fetch;
}
const result = await isomorphicFetch(input, init);
if (ctx?.res) {
const cookiesFromApi = result.headers.get('set-cookie');
if (cookiesFromApi) {
ctx?.res.setHeader('set-cookie', cookiesFromApi);
}
}
return result;
};
const cookieLink = createCookieLink(ctx);
const httpLink = persistedLink.concat(
new HttpLink({
uri: `${config.wordpress.backend}/graphql`,
fetchOptions,
fetch: fetchWithCookies,
useGETForQueries: true,
})
);
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: cookieLink.concat(httpLink),
cache: new InMemoryCache().restore(initialState || {}),
});
}
this is the URL of the request, as you can see its quite big. the problem is apollo wants to use the query and not the persisted query id. this request causes a http 414 code. one of the fixes is to make another query for the fragments
https://example.com/wp/graphql?query=query%20GetFrontPage%20%7B%0A%20%20page%3A%20pageOnFront%20%7B%0A%20%20%20%20nodes%20%7B%0A%20%20%20%20%20%20...PageData%0A%20%20%20%20%20%20__typename%0A%20%20%20%20%7D%0A%20%20%20%20__typename%0A%20%20%7D%0A%7D%0A%0Afragment%20PageData%20on%20Page%20%7B%0A%20%20title%0A%20%20content%0A%20%20link%0A%20%20excerpt%0A%20%20pageTemplate%0A%20%20hero%20%7B%0A%20%20%20%20heroColor%0A%20%20%20%20heroImage%20%7B%0A%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20altText%0A%20%20%20%20%20%20__typename%0A%20%20%20%20%7D%0A%20%20%20%20heroTitle%0A%20%20%20%20heroTitleTop%0A%20%20%20%20heroDescription%0A%20%20%20%20__typename%0A%20%20%7D%0A%20%20featuredImage%20%7B%0A%20%20%20%20...FeaturedImage%0A%20%20%20%20__typename%0A%20%20%7D%0A%20%20seo%20%7B%0A%20%20%20%20...Seo%0A%20%20%20%20__typename%0A%20%20%7D%0A%20%20...FlexContentPage%0A%20%20__typename%0A%7D%0A%0Afragment%20Seo%20on%20PostTypeSEO%20%7B%0A%20%20title%0A%20%20metaDesc%0A%20%20metaKeywords%0A%20%20metaRobotsNofollow%0A%20%20metaRobotsNoindex%0A%20%20canonical%0A%20%20opengraphTitle%0A%20%20opengraphDescription%0A%20%20opengraphImage%20%7B%0A%20%20%20%20sourceUrl(size%3A%20FEATIMGSOCIAL)%0A%20%20%20%20__typename%0A%20%20%7D%0A%20%20twitterTitle%0A%20%20twitterDescription%0A%20%20twitterImage%20%7B%0A%20%20%20%20sourceUrl(size%3A%20FEATIMGSOCIAL)%0A%20%20%20%20__typename%0A%20%20%7D%0A%20%20__typename%0A%7D%0A%0Afragment%20FlexContentPage%20on%20Page%20%7B%0A%20%20flexContent%20%7B%0A%20%20%20%20flexiblecontent%20%7B%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_SellingPoints%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20subtitle%0A%20%20%20%20%20%20%20%20sellingpointsBackgroundColor%0A%20%20%20%20%20%20%20%20cta%20%7B%0A%20%20%20%20%20%20%20%20%20%20target%0A%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20url%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20list%20%7B%0A%20%20%20%20%20%20%20%20%20%20listTitle%0A%20%20%20%20%20%20%20%20%20%20pointsList%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20point%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Titlelayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20titleBackgroundcolor%0A%20%20%20%20%20%20%20%20titles%20%7B%0A%20%20%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20%20%20titleTitle%0A%20%20%20%20%20%20%20%20%20%20titleTitleColor%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Testemonial%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20testemonial%0A%20%20%20%20%20%20%20%20facts%20%7B%0A%20%20%20%20%20%20%20%20%20%20factCount%0A%20%20%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20%20%20factTitle%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Pointslayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20points%20%7B%0A%20%20%20%20%20%20%20%20%20%20itemdescription%0A%20%20%20%20%20%20%20%20%20%20itemtitle%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Bloglayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20blogSubtitle%0A%20%20%20%20%20%20%20%20blogCta%20%7B%0A%20%20%20%20%20%20%20%20%20%20target%0A%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20url%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20blogCases%20%7B%0A%20%20%20%20%20%20%20%20%20%20...%20on%20Post%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20%20%20uri%0A%20%20%20%20%20%20%20%20%20%20%20%20details%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20broad%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20customer%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20normal%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20small%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20subtitle%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20video%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mediaItemUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20slug%0A%20%20%20%20%20%20%20%20%20%20%20%20featuredImage%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20node%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20blogTitle%0A%20%20%20%20%20%20%20%20blogColor%0A%20%20%20%20%20%20%20%20blogSubtitle%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Latestlayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20latestTitle%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Testlayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20testTitle%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Textlayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20wysiwyg%0A%20%20%20%20%20%20%20%20backgroundcolor%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Gallerylayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20photos%20%7B%0A%20%20%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20%20%20pullup%0A%20%20%20%20%20%20%20%20%20%20photo%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Visuallayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20image%20%7B%0A%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Customerslayout%20%7B%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20backgroundColor%0A%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20subtitle%0A%20%20%20%20%20%20%20%20customers%20%7B%0A%20%20%20%20%20%20%20%20%20%20link%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20target%0A%20%20%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20%20%20url%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20logo%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Slidelayout%20%7B%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20ctaLink%20%7B%0A%20%20%20%20%20%20%20%20%20%20target%0A%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20url%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20slideBigTitle%0A%20%20%20%20%20%20%20%20slideBigDescription%0A%20%20%20%20%20%20%20%20slideContent%20%7B%0A%20%20%20%20%20%20%20%20%20%20slideImage%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20slideColor%0A%20%20%20%20%20%20%20%20%20%20slideTitle%0A%20%20%20%20%20%20%20%20%20%20slideDescription%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Teamlayout%20%7B%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20teamContent%20%7B%0A%20%20%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20%20%20teamMemberName%0A%20%20%20%20%20%20%20%20%20%20teamMemberRole%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20teamBigTitle%0A%20%20%20%20%20%20%20%20teamBigSubtitle%0A%20%20%20%20%20%20%20%20teamContent%20%7B%0A%20%20%20%20%20%20%20%20%20%20teamMemberName%0A%20%20%20%20%20%20%20%20%20%20teamMemberRole%0A%20%20%20%20%20%20%20%20%20%20teamMemberImage%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Awardslayout%20%7B%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20awardsTitle%0A%20%20%20%20%20%20%20%20awardsBackgroundColor%0A%20%20%20%20%20%20%20%20awardsSubtitle%0A%20%20%20%20%20%20%20%20awards%20%7B%0A%20%20%20%20%20%20%20%20%20%20awardLink%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20target%0A%20%20%20%20%20%20%20%20%20%20%20%20title%0A%20%20%20%20%20%20%20%20%20%20%20%20url%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20awardLogo%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20awardImage%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20sourceUrl%0A%20%20%20%20%20%20%20%20%20%20%20%20altText%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20awardPrize%0A%20%20%20%20%20%20%20%20%20%20awardProject%0A%20%20%20%20%20%20%20%20%20%20awardOrganisation%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20...%20on%20Page_Flexcontent_Flexiblecontent_Accordionlayout%20%7B%0A%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20fieldGroupName%0A%20%20%20%20%20%20%20%20accordionBackgroundColor%0A%20%20%20%20%20%20%20%20accordionItems%20%7B%0A%20%20%20%20%20%20%20%20%20%20accordionTitle%0A%20%20%20%20%20%20%20%20%20%20accordionContent%0A%20%20%20%20%20%20%20%20%20%20accordionServices%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20accordionService%0A%20%20%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20__typename%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20__typename%0A%20%20%20%20%7D%0A%20%20%20%20__typename%0A%20%20%7D%0A%20%20__typename%0A%7D%0A%0Afragment%20FeaturedImage%20on%20NodeWithFeaturedImageToMediaItemConnectionEdge%20%7B%0A%20%20node%20%7B%0A%20%20%20%20link%0A%20%20%20%20sourceUrl(size%3A%20FEATIMGSOCIAL)%0A%20%20%20%20altText%0A%20%20%20%20title%0A%20%20%20%20mediaDetails%20%7B%0A%20%20%20%20%20%20width%0A%20%20%20%20%20%20height%0A%20%20%20%20%20%20__typename%0A%20%20%20%20%7D%0A%20%20%20%20__typename%0A%20%20%7D%0A%20%20__typename%0A%7D&operationName=GetFrontPage&variables=%7B%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%22e429ca4a5a03ff00fd8e895c639f032e66a3b212ced449b733d8a38693458419%22%7D%7D
What I want is that apollo automatically uses queryId as seen on but I just can't figure out what could lead to a solution. if you have any suggestions I would love to hear them.
it looks like the only solution is to split up the query into multible parts
I am using fetch to call backend API, th eprobelm is the backend security is a token, for security purpose we can not expose this token on public configuration.
I wanted to know if it is possible to put the token on server side params and then when we call fetch params is not visible in chrome debug and use only on NITRO following this text
Nitro allows 'direct' calling of routes via the globally-available $fetch helper. This will make an API call to the server if run on the browser, but will directly call the relevant function if run on the server, saving an additional API call.
$fetch API is using my fetch, with key features including:
This is my code
let recipientWebDTO = {};
recipientWebDTO.email = this.form.email;
recipientWebDTO.subscriptions = [{
"mailingListUnid": useRuntimeConfig().UNID
}];
const { status } = await $fetch
.raw(useRuntimeConfig().public.REST_API, {
method: "POST",
body: recipientWebDTO,
headers: {
"Content-Type": "application/json",
Authorization: useRuntimeConfig().TOKEN,
},
})
.then((response) => ({
status: response.status,
}))
.catch((error) => ({
status: error?.response?.status || 500,
}));
And my config file
export default defineNuxtConfig({
runtimeConfig: {
UNID: '58',
COMPANY_UNID: '3',
TOKEN: '78f77',
public: {
REST_API: process.env.REST_API || 'http://localhost:8080/rest/mailinglist/register/v1'
},
},
css: ["#/assets/_main.scss"],
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: '#use "#/assets/_colors.scss" as *;'
}
}
}
}
})
I want UNID, COMPANY_UNID, TOKEN to be visible only on server side, here it is just undefined, have I to create a middleware to handle it ? If yes, how I can use the same project to make it work ?
To manage to do it i added a server part as it is explained here:
Server api nuxtjs3 documentation
I created a directory server/api then my ts file with my proxy call where i use my token. Then in my vue i call my api. it means on browser the server file is invisible, and parameters and token nt accessibles.
in my vue:
const { status } = await $fetch.raw( '/api/newsletter', { method: "POST", body: this.form.email } )
in my server file:
export default defineEventHandler(async (event) => {
const runtimeConfig = useRuntimeConfig();
const subscriber = await readBody(event);
console.log("url used for rest call" + runtimeConfig.REST_API);
let recipientWebDTO = {
email: subscriber,
subscriptions: [{
"mailingListUnid": runtimeConfig.UNID
}]
};
const status = await $fetch.raw(runtimeConfig.REST_API, {
method: "POST",
body: recipientWebDTO,
headers: {
Authorization: runtimeConfig.TOKEN,
},
}).then((response) => ({
status: response.status,
}))
.catch((error) => ({
status: error?.response?.status || 500,
}));
return status;
})
The only complexity i have is i wanted to get a specific status but i always have the api call status, is 200 i wanted to simply forward the result but in NUXTJS is in WIP.
how to disable prepareHeaders on specific endpoint?, for example, i dont need authorization header on login or register endpoint, but on some endpoint i need authorization headers.
export const backendService = createApi({
reducerPath: 'backend',
baseQuery: fetchBaseQuery({
baseUrl: `${Endpoint}`,
prepareHeaders: (headers, {getState}) => {
const token = getState().auth.token;
if (token) {
headers.set('authorization', `Bearer ${token}`);
}
headers.set('Access-Control-Allow-Origin', '*');
return headers;
},
}),
tagTypes: ['Question', 'Questions'],
endpoints: build => ({
registerUser: build.mutation({ <------ skip prepareHeaders in register
query: body => ({
url: 'auth/local/register',
method: 'POST',
body,
}),
}),
login: build.mutation({ <------- skip prepareHeaders on login
query: body => ({
url: 'auth/local',
method: 'POST',
body,
}),
}),
getCategories: build.query({ <------ apply prepareHeaders
query: () => {
return {
url: 'categories'
};
},
}),
}),
});
The current beta for RTK 1.7 passes the endpointname to prepareHeaders, so if you try that you should be able to work around that.
The BaseQueryApi and prepareheaders args now include fields for endpoint name, type to indicate if it's a query or mutation, and forced to indicate a re-fetch even if there was already a cache entry. These can be used to help determine headers like Cache-Control: no-cache.
I am attempting to implement NextAuth in my NextJs app. I am following the official documentation. But for one reason or the other, it seems like the user session object is not generated on login.
Here is my code from my pages/api/auth/[...nextauth].js file
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
import axios from "axios";
export default (req, res) =>
NextAuth(req, res, {
providers: [
Providers.Credentials({
id: 'app-login',
name: APP
authorize: async (credentials) => {
console.log("credentials_:", credentials);
try {
const data = {
username: credentials.username,
password: credentials.password
}
// API call associated with authentification
// look up the user from the credentials supplied
const user = await login(data);
if (user) {
// Any object returned will be saved in `user` property of the JWT
return Promise.resolve(user);
}
} catch (error) {
if (error.response) {
console.log(error.response);
Promise.reject(new Error('Invalid Username and Password combination'));
}
}
},
}),
],
site: process.env.NEXTAUTH_URL || "http://localhost:3000",
session: {
// Use JSON Web Tokens for session instead of database sessions.
// This option can be used with or without a database for users/accounts.
// Note: `jwt` is automatically set to `true` if no database is specified.
jwt: true,
// Seconds - How long until an idle session expires and is no longer valid.
maxAge: 1 * 3 * 60 * 60, // 3 hrs
// Seconds - Throttle how frequently to write to database to extend a session.
// Use it to limit write operations. Set to 0 to always update the database.
// Note: This option is ignored if using JSON Web Tokens
updateAge: 24 * 60 * 60, // 24 hours
},
callbacks: {
// signIn: async (user, account, profile) => { return Promise.resolve(true) },
// redirect: async (url, baseUrl) => { return Promise.resolve(baseUrl) },
// session: async (session, user) => { return Promise.resolve(session) },
// jwt: async (token, user, account, profile, isNewUser) => { return Promise.resolve(token) }
},
pages: {
signIn: '/auth/credentials-signin',
signOut: '/auth/credentials-signin?logout=true',
error: '/auth/credentials-signin', // Error code passed in query string as ?error=
newUser:'/'
},
debug: process.env.NODE_ENV === "development",
secret: process.env.NEXT_PUBLIC_AUTH_SECRET,
jwt: {
secret: process.env.NEXT_PUBLIC_JWT_SECRET,
}
});
const login = async data => {
var config = {
headers: {
'Content-Type': "application/json; charset=utf-8",
'corsOrigin': '*',
"Access-Control-Allow-Origin": "*"
}
};
const url = remote_user_url;
const result = await axios.post(url, data, config);
console.log('result', result);
return result;
};
What am I not getting it right here? Thanks for the help.
I managed to resolve the issue eventually. Something was wrong due to specifying the 'id' and 'name' options for the custom credential provider
I have removed them and the code is working now.
For the following code:
const apolloClient = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: endpoint,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
}
})
});
I need to get endpoint and token asynchronously. How may I do this?
Thank you
You can use apollo-link-context to modify your requests. You can cache the values as shown if you don't fetch them on every request.
let token
let uri
const contextLink = setContext(async () => {
if (!token) {
token = await getTokenAsync()
}
if (!uri) {
uri = await getUriAsync()
}
return { uri, token }
});
const client = new ApolloClient({
...
link: ApolloLink.from([
contextLink,
httpLink,
])
})
The above is the preferred way of dynamically setting these parameters. Alternatively, you could just fetch the token and URI before rendering your ApolloProvider and then dynamically create your client instance based on the values.