Authentication in Prisma - Part 3: Validation


While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

In Part 2 of this series we covered how to generate a temporary token for our user whenever they login or create an account. Now we’re going to wrap it up by restricting our data to only certain authorized users.

Getting our User

When we create a token, we’re going to be giving it our user’s id and then use that id and jwt.verify to return data pertaining to that user if the verification was successful.

The first step is to setup our context to handle the headers from the user’s request. If we change our context parameter to a function it will automatically have access to our request as an argument.

const server = new GraphQLServer({
  typeDefs: './schema.graphql',
  context(req) { return { prisma, req } }

Now we should be able to destructure the req object out of our context. If you try logging req you’ll see that there is a request.headers which will contain the authorization we passed into the GraphQL Playground. This is what we’ll give to jwt.verify with our secret to check if that user is valid. Since we’ll be doing this for every resolver we want to secure, let’s make it a function.

It’s pretty straightforward, we’re just getting our token from the header, removing Bearer so only the token is left, verify it, and return our user’s id.

const getUser = req => {
  const authorization = req.request.headers.authorization;

  if (!authorization) throw new Error('Authentication Required');
  else {
    const token = authorization.replace('Bearer ', '');
    const user = jwt.verify(token, process.env.TOKEN_SECRET);

    return user.userId;


Let’s add a few new resolvers into our schema first. We’re just going to practice with a currentUser query, deleteAccount and updateUser mutations, and a myAccount subscription.

type Query {
  users: [User!]!
  currentUser: User!

type Mutation {
  createUser(data: CreateUserInput): User!
  loginUser(email: String!, password: String!): User!
  deleteAccount: User!
  updateUser(data: UpdateUserInput): User!

type Subscription {
  myAccount: AccountSubscription!

type User {
  id: ID!
  name: String!
  email: String!
  password: String! 
  token: String

input CreateUserInput {
  name: String! 
  email: String!
  password: String!

input UpdateUserInput {
  name: String 
  email: String
  password: String

enum MutationType {

type AccountSubscription {
  mutation: MutationType!
  node: User


Authentication is now going to be incredibly simple, just get our user’s id with getUser and pass that to where. Now it will return data for the user that’s logged in and only that user.

const Query = {
  users(parent, args, { prisma }, info) { ... },
  currentUser(parent, args, { req, prisma }, info) {
    const userID = getUser(req);

    return prisma.query.user({ where: { id: userID } }, info);


Mutations are just as easy, except with updates we’ll want to check if they’re changing their password first, since we’ll need to rehash it first.

const Mutation = {
  async createUser(parent, { data }, { prisma }, info) { ... },
  async loginUser(parent, { email, password }, { prisma }, info) { ... },

  async deleteAccount(parent, args, { prisma, req }, info) {
    const userID = getUser(req);

    return prisma.mutation.deleteUser({ where: { id: userID } }, info);
  async updateUser(parent, args, { prisma, req }, info) {
    const userID = getUser(req);

    if (typeof args.data.password === 'string') args.data.password = await bcrypt.hash(args.data.password, 10);

    return prisma.mutation.updateUser({
      where: { id: userID },
      data: args.data
    }, info);


Subscriptions are just as self-explanatory once again, just remember to add Subscription to your resolvers in index.js.

const Subscription = {
  myAccount: {
    subscribe(parent, args, { prisma, req }, info) {
      const userID = getUser(req);

      return prisma.subscription.user({ where: { node: { id: userID } } }, info);

Closing Thoughts

That may have seemed like a lot of work, but actually using authentication is by far the easiest part of the process. The important thing is to understand how it works even though you’ll most likely be utilizing a starter boilerplate for most of your real projects.

Creative Commons License