Hi,
I have read all posts on this in the community here. Unfortunately, I still wasn't able to set this up properly.
The documentation says:
*Accepts an email and password. On success, it will return the logged in user as well as a token that can be used to authenticate. In the GraphQL and REST APIs, this operation also automatically sets an HTTP-only cookie including the user's token. *
Does this mean if I make a GraphQL request from my Next.js frontend, a http only cookie is set with the name
"payload-token"and the token as the value? In my case, the request works successfully, just the cookie is not being set.
mutation loginUser($email: String!, $password: String!) {
loginUser(email: $email, password: $password) {
user {
email
}
exp
token
}
}{
user: {
email: 'dev@payloadcms.com',
createdAt: "2020-12-27T21:16:45.645Z",
updatedAt: "2021-01-02T18:37:41.588Z",
id: "5ae8f9bde69e394e717c8832"
},
token: '34o4345324...',
exp: 1609619861
}on the request is "credentials: 'include'" set?
I'm not super familiar with graphql
A user recently had this issue though, check out this thread:
https://discord.com/channels/967097582721572934/1037865004545888287Damn! That was the solution. Thanks
@1049775120559898725I thought I have to include the credentials for every request after login. Didn't know it is required for the login as well.
Might be good to add this to the docs here:
Agreed, this is a common issue and I'm not sure if excluding the "credentials" property from the example is intentional.
@808734492645785600
@281120856527077378
Thoughts?
The
credentials: includeproperty is to attach an already existing token to the outgoing request, so that should have no effect as to why your token was not being attached in the response. Here's the official gql auth example:
https://github.com/payloadcms/payload/blob/master/examples/auth/next-app/app/_components/Auth/index.tsx#L49mutation {
loginUser(email: "${args.email}", password: "${args.password}") {
user {
${USER}
}
exp
}
}That’s what I thinking as well. That’s why I didn’t include it. Fact is, that the cookie is only set if I include
credentials: include. You can see my request above. I do get the correct user return. Just the cookie is not set. Could it be a problem to send
credentials: includewith the login request at some point?
It could be related to your cookie domain, is your front end running on a different domain than your CMS?
If that’s the case, set your cookie domain to
localhostor whatever your top level domain is, no protocol or port.
Set this via
auth.cookies.domainin your users collection
I added the domain. Still doesn't work.
Ok check your browser’s application tab for the list of cookies that are attached
You might find that the payload-token is set, but not with the correct properties
The list is empty
Here is my auth collection. Maybe I did something wrong here:
const Users: CollectionConfig = {
slug: 'users',
access: {
create: isAdmin,
read: () => true,
update: isAdminOrSelf,
delete: isAdminOrSelf,
},
auth: {
useAPIKey: true,
maxLoginAttempts: 10,
cookies: {
domain: 'localhost',
},
},
admin: {
useAsTitle: 'name',
group: 'Settings',
},
fields: [
// Email added by default
// Add more fields as needed
{
label: 'Name',
name: 'name',
type: 'text',
},
{
name: 'roles',
type: 'select',
hasMany: true,
defaultValue: ['public'],
required: true,
access: {
read: isAdminOrSelfFieldLevel,
create: isAdminFieldLevel,
update: isAdminFieldLevel,
},
options: ['admin', 'public'],
},
],
};Could this be caused by the access functions?
No your access functions look fine. For reference here's the
cookiesconfig in the official auth example:
https://github.com/payloadcms/payload/blob/master/examples/auth/cms/src/collections/Users.ts#L14But based on the fact that you don't a cookie at all in your browser, tells me this is probably because of missing or misconfigured
csrfsettings:
https://github.com/payloadcms/payload/blob/master/examples/auth/cms/src/payload.config.ts#L12I have set it up like in the example.
Here is my payload config:
export default buildConfig({
serverURL: 'http://localhost:3000',
globals: [SiteSettings, HeaderNavigation, FooterNavigation],
collections: [
FormSubmissions,
Pages,
Images,
Icons,
Services,
ServiceTypes,
Forms,
Redirects,
BrandAssets,
OutgoingLinks,
Users,
],
admin: {
user: Users.slug,
},
csrf: [
// whitelist of domains to allow cookie auth from
'http://localhost:3000',
'http://localhost:3001',
],
cors: [
// whitelist of domains to allow cookie auth from
'http://localhost:3000',
'http://localhost:3001',
],
typescript: {
outputFile: path.resolve(__dirname, 'payload-types.ts'),
},
graphQL: {
schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'),
},
debug: true,
});Still not working
Odd! That seems like a correctly configured setup
And your client application is definitely served from 3000/3001?
yes. The client application runs on 3001
hmm
And sorry, you're positive the cookie is not being set?
The cookie is only set if I add
credentials: includeto the login request. Not without that.
hmm
Maybe we can modify the cookie settings as a test
It's definitely odd that it sets it when credentials are included
Generally I'd say wait until we get some more clarification, but if you're down to try a couple of fixes let me know
For instance, I add a cors config in my
server.tsBut in any case
Sure I can try a couple of things
What does your login request look like?
The .env var:
NEXT_PUBLIC_PAYLOAD_API_URL=
http://localhost:3000/api/graphqlThe GraphQL client function:
export const graphqlAppLoginClient = new GraphQLClient(
process.env.NEXT_PUBLIC_PAYLOAD_API_URL as string
);The request:
const req = await graphqlAppLoginClient.request(sentLoginRequestQuery, {
email: data.email,
password: data.password,
});And do following requests fail without the cookie being set?
for instance, hitting an authenticated endpoint
Also, if you can provide a screenshot of the logged request in your dev tools, that would be helpful, please
Ok I tested querying the users where I have one admin and one public user. With both users I'm getting the following log:
The admin should get both users returned. The public user should get the
not allowedresponse.
Apologies, could you translate the error?
Ah so indeed, the cookies are not set
Yes
We can investigate this a bit more, but in the meantime, is there any downside (apart from non standard) to adding credentials: include to the login request if that was working?
Obviously we want to get this sorted out
But I'm starting to question the source of the issue haha
I wonder if you made a new payload blank project real quick, if you run into the same issues
For me it's not a problem. I wasn't sure if there is any problem with that, which I'm not aware of.
I think the only concern was that you shouldn't HAVE to
It is very odd though
I'm using graphql-request. Maybe it has to do with that. I will try setting up a new payload later. I'll get back to you when I'm done.
Yeah true.
Sounds good! And hopefuly we can figure out what the issue is!
Star
Discord
online
Get dedicated engineering support directly from the Payload team.