How to use GraphiQL with Secure Services?

When I add this to my services I get an authentication error when trying to test them in GraphiQL:

export const beforeResolver = (rules) => {
  rules.add(requireAuth)
}

In GraphiQl I include a valid new token in the HTTP headers section:

{
  "Authorization": "Bearer freshtoken"
  "auth-provider": "netlify"
}

Anyone else faced the same issue?

Hi @darryl-snow what does your requireAuth do to enforce?

By default, auth is


/**
 * Once you are ready to add authentication to your application
 * you'll build out requireAuth() with real functionality. For
 * now we just return `true` so that the beforeResolver() calls
 * in services have something to check against, simulating a logged
 * in user that is allowed to access that service.
 *
 * See https://redwoodjs.com/docs/authentication for more info.
 */

export const requireAuth = () => {
  return true
}

But I assume you are now using Netlify Identity – and that by freshtoken the JWT has not expired.

I’ll have to try this out later in one of my test Netlify apps and hope to have an update.

Thanks for raising this issue.

Here’s my lib/auth.js - I don’t think I’ve made any changes to what was generated or whatever was in the Tutorial. I’m using Netlify and I got the token form logging into my app and copying it from localstorage so I know it’s a valid token.

import { AuthenticationError, ForbiddenError, parseJWT } from '@redwoodjs/api'

/**
 * getCurrentUser returns the user information together with
 * an optional collection of roles used by requireAuth() to check
 * if the user is authenticated or has role-based access
 *
 * @param decoded - The decoded access token containing user info and JWT claims like `sub`
 * @param { token, SupportedAuthTypes type } - The access token itself as well as the auth provider type
 * @param { APIGatewayEvent event, Context context } - An object which contains information from the invoker
 * such as headers and cookies, and the context information about the invocation such as IP Address
 *
 * @see https://github.com/redwoodjs/redwood/tree/main/packages/auth for examples
 */
export const getCurrentUser = async (
  decoded,
  { _token, _type },
  { _event, _context }
) => {
  return { ...decoded, roles: parseJWT({ decoded }).roles }
}

/**
 * Use requireAuth in your services to check that a user is logged in,
 * whether or not they are assigned a role, and optionally raise an
 * error if they're not.
 *
 * @param {string=} roles - An optional role or list of roles
 * @param {string[]=} roles - An optional list of roles
 * @returns {boolean} - If the currentUser is authenticated (and assigned one of the given roles)
 *
 * @throws {AuthenticationError} - If the currentUser is not authenticated
 * @throws {ForbiddenError} If the currentUser is not allowed due to role permissions
 *
 * @see https://github.com/redwoodjs/redwood/tree/main/packages/auth for examples
 */
export const requireAuth = ({ role } = {}) => {
  // if (!context.currentUser) {
  //   throw new AuthenticationError("You don't have permission to do that.")
  // }

  if (
    typeof role !== 'undefined' &&
    typeof role === 'string' &&
    !context.currentUser.roles?.includes(role)
  ) {
    throw new ForbiddenError("You don't have access to do that.")
  }

  if (
    typeof role !== 'undefined' &&
    Array.isArray(role) &&
    !context.currentUser.roles?.some((r) => role.includes(r))
  ) {
    throw new ForbiddenError("You don't have access to do that.")
  }
}