how to return token from graphql mutation

This is my code of mutation in which i use the type of User which has name,email,password and i make two mutations for the register the user and login the user. I have searched all the docs about the graphql and read all the blogs related to authentication but can't got the answer to return the token from the mutation

    const mutation = new GraphQLObjectType({
      name: "Mutation",
      fields: {
        addUser: {
          type: UserType,
          args: {
            name: { type: GraphQLString },
            email: { type: GraphQLString },
            password: { type: GraphQLString },
            avatar: { type: GraphQLString }
          },
          resolve(parentValue, args) {
            const avatar = gravatar.url(args.email);
            return bcrypt
              .hash(args.password, 10)
              .then(hash => {
               args.password = hash;
               const newUser = new User({
                  name: args.name,
                  email: args.email,
                  password: args.password,
                  avatar
                });
                return newUser
                  .save()
                  .then(user => user)
                  .catch(e => e);
              })
               .catch(e => e);
          }
        },
        login: {
          name: "Login",

          type: UserType,
          args: {
            email: { type: GraphQLString },
            password: { type: GraphQLString }
          },
          resolve(parentValue, args, context) {
            return User.findOne({ email: args.email })
              .then(user => {
                if (user) {
                  return bcrypt
                    .compare(args.password, user.password)
                    .then(isValid => {
                      if (!isValid) {
                        throw new Error({ message: "password Incrrect" });
                      } else {
                        const token = jwt.sign(
                          { name: user.name, id: user.id },
                          "mySecret"
                        );
                        return user;
                      }
                    })
                    .catch(e => e);
                } else {
                  throw new Error({ message: "email Incorrect" });
                }
              })
              .catch(e => e);
          }
        }
      }
    });

This is my User Type

    const UserType = new GraphQLObjectType({
      name: "User",
      fields: {
        id: { type: GraphQLString },
        name: { type: GraphQLString },
        email: { type: GraphQLString },
        password: { type: GraphQLString },
        avatar: { type: GraphQLString }
      }
    });

1 answer

  • answered 2018-07-11 07:58 MarcoDaniels

    I would advise you to update your UserType by removing the password field and add a token field like:

    const UserType = new GraphQLObjectType({
          name: "User",
          fields: {
            id: { type: GraphQLString },
            name: { type: GraphQLString },
            email: { type: GraphQLString },
            avatar: { type: GraphQLString },
            token: { type: GraphQLString }
          }
     });
    

    The reason is that UserType is a return type of the mutation, so it's "public", and maybe we should not send a password to public(as we are authenticating on the server side), but JWT is public, so we can send it back.

    And in your login mutation add the token into the user object, something like:

       login: {
          name: "Login",
          type: UserType,
          args: { email: { type: GraphQLString }, password: { type: GraphQLString } },
          resolve(parentValue, args, context) {
            return User.findOne({ email: args.email })
              .then(user => {
            .........
                        const token = jwt.sign(
                          { name: user.name, id: user.id },
                          "mySecret"
                        );
                        user.token = token;
                        return user;
                      }
            ........
          }
        }