I have need to authenticate myself in one of my nextjs lamba files which now lives inside /pages/api/*
I currently have a apollo.serverless.js file, this is imported into pages/api/users/update/role/[userId].js where I do my db interactions.
This is where it gets a little messy for me. I am not certain this is the only way to do it, but it is where my brain took me. I am passing the req intoapollo.serverless.js` so that I have access to the bearer token that is inside the cookies.
It may be as simple as having my setup incorrect for my apollo.client.
I am testing the link directly http://localhost:3000/api/users/update/role/dXNlcjoxMTg= as the stripe webhook will access this url directly with a query param.
pages/api/users/update/role/[userId].js
import { useQuery, useMutation } from '../../../../../lib/apollo/apollo.serverless'
import { updateMemberRole, allUsers } from '../../../queries/users'
export default async (req, res) => {
let data
try {
const mutationInfo = await useMutation(
{
mutation: updateMemberRole,
variables: {
userId: req.query.userId,
},
},
req
)
data = mutationInfo.data
} catch (err) {
data = err
}
res.status(200).json({ data })
}
Headers sent with [userId]
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,en-GB;q=0.8,fr;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Cookie: analyticsCookieAccepted=1; analyticsCookieNoticeClosed=1; _ga=GA1.1.2044509544.1574855120; wordpress_test_cookie=WP+Cookie+check; OPTOUTMULTI=0:0%7Cc4:0%7Cc3:0%7Cc2:0; wp-settings-45=editor%3Dhtml%26libraryContent%3Dbrowse%26imgsize%3Dfull; wp-settings-time-45=1575018303; theme=light; wp-settings-time-1=1575496501; utag_main=v_id:016eacdb7ad1001fa3af49cf1fec01069001606100fb8$_sn:18$_se:1$_ss:1$_st:1575891251585$ses_id:1575889451585%3Bexp-session$_pn:1%3Bexp-session; wordpress_logged_in_86a9106ae65537651a8e456835b316ab=glasshousegames%7C1578351721%7CtL4KMHIW7tTAUuCzUOJd8r6Mu5buST9mheH2tn9WFQs%7C593e133b11f6c0745f577e32d66db0cf1ccfa012504f9015fc64c515d2df77d2; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3QiLCJpYXQiOjE1NzgwNTgyOTIsIm5iZiI6MTU3ODA1ODI5MiwiZXhwIjoxNTc4NjYzMDkyLCJkYXRhIjp7InVzZXIiOnsiaWQiOiIxMTgifX19.iMSh4KjuON3otpOqO3TXpYAh2bQYu48sqm9pzsgeBis
Host: localhost:3002
Pragma: no-cache
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
apollo.serverless.js
import dotenv from 'dotenv'
import { fetch } from 'cross-fetch/polyfill'
import { createHttpLink } from 'apollo-link-http'
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { setContext } from 'apollo-link-context'
import { onError } from 'apollo-link-error'
import { ApolloLink } from 'apollo-link'
import { graphQL } from 'app.config'
import ApolloClass, { sortParams } from '~/lib/apollo/apollo.class'
dotenv.config()
const apolloClient = ({ cookies: { token = null }, headers }) => {
const authLink = setContext(_ => {
return {
headers: {
...headers,
authorization: `Bearer ${token}`,
},
}
})
return new ApolloClient({
link: ApolloLink.from([
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}`)
}),
authLink.concat(
createHttpLink({
uri: graphQL,
credentials: 'same-origin',
fetch: fetch,
})
),
]),
cache: new InMemoryCache(),
})
}
export const useQuery = async function(query) {
const { options = {} } = sortParams([...arguments])
const { loading, data: queryData, error, ...props } = await apolloClient.query({
query,
...options,
})
let transformData = {}
if (queryData) transformData = new ApolloClass(queryData).start()
return {
queryData,
error,
loading,
data: transformData,
}
}
export const useMutation = async function(mutation, req) {
const { data } = await apolloClient(req).mutate(mutation)
return { data }
}
Error
// 20200106132714
// http://localhost:3002/api/users/update/role/dXNlcjoxMTg=
{
"data": {
"graphQLErrors": [
{
"message": "You do not have the appropriate capabilities to perform this action",
"category": "user",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"updateUser"
]
}
],
"networkError": null,
"message": "GraphQL error: You do not have the appropriate capabilities to perform this action"
}
}
So I believe the problem is that my headers are not being sent, as I cannot see them in the headers detailed here , I can not see them in my headers when looking http://localhost:3000/api/users/update/role/cm9sZTpzdGFuZGFyZA==
It is worth mentioning I am using GraphQL and wp-GraphQL with JWT as my auth token. And handling the JWT tokens withJWT Authentication for WP REST API. The reason I am not drawing more attention to this is that I cannot see any Bearer SomeToken in my headers, so I am sure once the token is sent over everything work. JWT is correctly working in all my interactions from the cookie.
from How to implement authentication in Next.js pages/api folder with Apollo Client
No comments:
Post a Comment