I have a GQL mutation called login, which returns a JWT as a cookie in the response.
Although the Set-Cookie
header is present, nothing appears in my local storage tab. Nothing gets printed in my console either...
Here's my login mutation
@Mutation((returns) => AuthenticatedUser)
async login(
@Context() context: Auth.GqlContext,
@Args('payload', { type: () => UserLoginDto }) payload: UserLoginDto
): Promise<AuthenticatedUser> {
const authenticatedUser = await this.authService.login(payload)
context.res.cookie('jwt', authenticatedUser.jwt, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 1000 * 60 * 60 * 24 * 31, // one month
domain: process.env.NODE_ENV === 'production' ? '.herbievine.com' : undefined
})
return authenticatedUser
}
Example response as JSON:
{
"data": {
"login": {
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjI0N2QyNmY3LTM3NzQtNGRiNS1hM2MzLTE2MTg3Mzk2ODdlMCIsImVtYWlsIjoidmluZWhlcmJpZUBnbWFpbC5jb20iLCJpYXQiOjE2MzYxMjkyMTksImV4cCI6MTYzODcyMTIxOX0.hHHAAgzs7wFjMP2C565fGGHAd0o-C9h-jA5qzm48OdE",
"user": {
"email": "[email protected]",
"name": "Some Name"
}
}
}
}
Response:
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:4000
Vary: Origin
Access-Control-Allow-Credentials: true
Set-Cookie: jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjI0N2QyNmY3LTM3NzQtNGRiNS1hM2MzLTE2MTg3Mzk2ODdlMCIsImVtYWlsIjoidmluZWhlcmJpZUBnbWFpbC5jb20iLCJpYXQiOjE2MzYxMjkyMTksImV4cCI6MTYzODcyMTIxOX0.hHHAAgzs7wFjMP2C565fGGHAd0o-C9h-jA5qzm48OdE; Max-Age=2678400; Path=/; Expires=Mon, 06 Dec 2021 16:06:11 GMT; HttpOnly; SameSite=Lax
Content-Type: application/json; charset=utf-8
Content-Length: 319
ETag: W/"13f-MuV4uipvL8ui1YJXuTSvJ1TM1H0"
Date: Fri, 05 Nov 2021 16:06:11 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Request:
POST /graphql HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:3000/graphql
content-type: application/json
Origin: http://localhost:3000
Content-Length: 195
Connection: keep-alive
For the moment, I still haven't setup my front-end codebase, which will be set to http://localhost:4000. This is all being tested in the GraphQL playground
Update
config for gql playground:
{
"editor.cursorShape": "line",
"editor.fontFamily": "'Source Code Pro', 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace",
"editor.fontSize": 14,
"editor.reuseHeaders": true,
"editor.theme": "dark",
"general.betaUpdates": false,
"prettier.printWidth": 80,
"prettier.tabWidth": 2,
"prettier.useTabs": false,
"request.credentials": "omit",
"schema.disableComments": true,
"schema.polling.enable": true,
"schema.polling.endpointFilter": "*localhost*",
"schema.polling.interval": 2000,
"tracing.hideTracingResponse": true,
"queryPlan.hideQueryPlanResponse": true
}
App Module:
@Module({
imports: [
GraphQLModule.forRoot({
autoSchemaFile: join(process.cwd(), 'schema.gql'),
context: ({ req, res }) => ({ req, res }),
cors: {
origin:
process.env.NODE_ENV === 'production'
? '.herbievine.com'
: 'http://localhost:4000',
credentials: true,
}
}),
ThrottlerModule.forRoot({
ttl: 60,
limit: 20
}),
PostsModule,
CategoriesModule,
UsersModule,
AuthModule
],
controllers: [AppController],
providers: [AppService, PrismaService]
})
export class AppModule {}
Auth Module:
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secret: process.env.JWT_SECRET,
signOptions: {
expiresIn: '30d'
}
})
],
providers: [
PrismaService,
JwtStrategy,
LocalStrategy,
AuthService,
UsersService,
AuthResolver
],
controllers: [AuthController],
exports: [AuthService]
})
export class AuthModule {}
CodePudding user response:
The GQL playground by default doesn't send credentials. In the options of the GQL playground, set request.credentials = 'include'
and it should work