Custom github JWT Auth with Redwood Auth

There’s a certain amount of polish needed to write docs on GH, but what I can do to help is write a summary here and add a link in the GH

Build auth endpoint into the api project:

Write the SDL

In my case I was building phone auth stored in the local database. Design your SDL and put it in /api/src/graphql/auth.sdl.js

# Passwordless example
type Mutation {
  authChallenge(input: AuthChallengeInput!): AuthChallengeResult
  authVerify(input: AuthVerifyInput!): AuthVerifyResult # Should return a token
}

# Username/password example
type Mutation {
  authRegister(input: AuthRegisterInput!): AuthRegisterResult
  authLogin(input: AuthLoginInput!): AuthLoginResult # Should return a token
  authVerify(input: AuthVerifyInput!): AuthVerifyResult
  authForgotPassword(input: AuthForgotPasswordInput!): AuthForgotPasswordResult
}

Write the Service

In /api/src/services/auth/auth.js

export const authChallenge = async (input) => { return { success: true } }
// ...etc

Write a token validator and user resolver

In /api/src/lib/auth.js:

import { AuthenticationError } from '@redwoodjs/api'

export const getCurrentUser = async (token) => {
  // Resolve and return user record
}

export const requireAuth = () => {
  if (!context.currentUser) {
    throw new AuthenticationError("You don't have permission to do that.")
  }
}

Add the user resolver to the GraphQL endpoint

In /api/src/functions/graphql.js:

import { getCurrentUser } from 'src/lib/auth' // Add this line

export const handler = createGraphQLHandler({
  getCurrentUser, // Add this line
  schema: makeMergedSchema({
    schemas,
    services: makeServices({ services }),
  }),
  onException: () => {
    // Disconnect from your database with an unhandled exception.
    db.$disconnect()
  },
})

Authenticate via HTTP Headers!

Add Authorization: Bearer TOKEN and replace TOKEN with your token value
Add Auth-Provider: custom

Viola! You should be able to authenticate using a custom provider now.

Implement Frontend Client

I haven’t implemented this, but you’ll also need to implement the UI to hit your backend endpoints.

3 Likes