⚠️
This is the documentation for the old GraphQL Yoga version 4. We recommend upgrading to the latest GraphQL Yoga version 5.
Migrate to GraphQL Yoga v5
Migrate to GraphQL Yoga v5
JWT
A JSON Web Tokens (JWT) is a signed token containing arbitrary informations, commonly used for authentication. By being signed by the issuer of the token, it can be verified that the token is valid and has not been tampered with.
GraphQL Yoga provides a plugin to easily integrate JWT into your API.
Installation
npm i @graphql-yoga/plugin-jwt
Usage
import { createSchema, createYoga } from 'graphql-yoga'
import jwt from 'jsonwebtoken'
import { useJWT } from '@graphql-yoga/plugin-jwt'
import { getUserById, getUserByLogin } from './db'
const signingKey = process.env.JWT_SECRET
const yoga = createYoga({
schema: createSchema({
typeDefs: `
type Query {
me: User
}
type Mutation {
login(email: String!, password: String!): String
}
`,
resolvers: {
Query: {
me: (parent, args, ctx) => {
// The content of the JWT can be found in the context
if (!ctx.jwt) {
// No JWT token provided, we are not authenticated
return null
}
return getUserById(ctx.jwt.sub)
}
},
Mutation: {
login: (parent, { email, password }) => {
const user = getUserByLogin(email, password)
if (!user) {
throw new GraphqlError('Invalid credentials')
}
// Client will receive a JWT token, it will then can be used in 'authorization' header
return jwt.sign({ username: user.name }, signingKey, {
subject: user.id
})
}
}
}
}),
plugins: [
useJWT({
issuer: 'http://graphql-yoga.com',
signingKey
})
]
})
const server = createServer(yoga)
server.listen(4000, () => {
console.log(`Server is running on http://localhost:4000/${server.graphqlEndpoint}`)
})
Usage with Cookies
Security best practices recommend to store JWT in a HTTP-only cookie. This way, the token cannot be accessed by JavaScript and is only sent to the server on each request.
To do so, you can use the getToken
option of the plugin to extract the token from the request’s
cookies.
import { createSchema, createYoga } from 'graphql-yoga'
import jwt from 'jsonwebtoken'
import { useJWT } from '@graphql-yoga/plugin-jwt'
import { useCookies } from '@whatwg-node/server-plugin-cookies'
import { getUserById, getUserByLogin } from './db'
const signingKey = process.env.JWT_SECRET
const yoga = createYoga({
schema: createSchema({
typeDefs: `
type Query {
me: User
}
type Mutation {
login(email: String!, password: String!): String
}
`,
resolvers: {
Query: {
me: (parent, args, ctx) => {
// The content of the JWT can be found in the context
if (!ctx.jwt) {
// No JWT token provided, we are not authenticated
return null
}
return getUserById(ctx.jwt.sub)
}
},
Mutation: {
login: (parent, { email, password }, ctx) => {
const user = getUserByLogin(email, password)
if (!user) {
throw new GraphqlError('Invalid credentials')
}
const token = jwt.sign({ username: user.name }, signingKey, {
subject: user.id
})
// Set the cookie on the response
ctx.request.cookieStore?.set({
name: 'authorization',
sameSite: 'strict',
secure: true,
domain: 'graphql-yoga.com',
expires: new Date(Date.now() + 1000 * 60 * 60 * 24),
value: token,
httpOnly: true
})
}
}
}
}),
plugins: [
useCookies(),
useJWT({
issuer: 'http://graphql-yoga.com',
signingKey,
getToken: ({ request }) => request.cookieStore?.get('authorization')
})
]
})
const server = createServer(yoga)
server.listen(4000, () => {
console.log(`Server is running on http://localhost:4000/${server.graphqlEndpoint}`)
})