Full Stack Authentication

I am working on an application. I have a React Typescript frontend and a Golang backend.
I trying to integrate Auth0 for authentication.

I created an SPA and named it app_client on Auth0 and used the clientID and domainID as my client ID and domain ID for the react client side. I also created a new api and named it app_server. I used the app_server Identifier as the audience for both the client and the server side of my application.

I am using useAuth0.GetAccessTokenSilently on the react end to get the token, however the backend is errors out 'Error parsing token: Invalid audience.`
I tested by hardcoding the test token from Auth0 and that does work.

Below is the react code for AUTH0 setup

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <BrowserRouter>
      <Auth0Provider
        domain=domain
        clientId=clientId
        authorizationParams={{
          audience: audience,
          redirect_uri: window.location.origin
        }}
      >
        <App />
      </Auth0Provider>
    </BrowserRouter>
  </React.StrictMode>,
)

Code for golang AUTH0 middleware

func main() {
	log.Println(os.Getenv("AUTH0_API_AUDIENCE"))
	jwtMiddleware := jwtmiddleware.New(jwtmiddleware.Options{
		ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
			aud := os.Getenv("AUTH0_API_AUDIENCE")
			checkAudience := token.Claims.(jwt.MapClaims).VerifyAudience(aud, false)
			if !checkAudience {
				return token, errors.New("Invalid audience.")
			}
			// verify iss claim
			iss := os.Getenv("AUTH0_DOMAIN")
			checkIss := token.Claims.(jwt.MapClaims).VerifyIssuer(iss, false)
			if !checkIss {
				return token, errors.New("Invalid issuer.")
			}
			cert, err := getPemCert(token)
			if err != nil {
				log.Fatalf("could not get cert: %+v", err)
			}
			result, _ := jwt.ParseRSAPublicKeyFromPEM([]byte(cert))
			return result, nil
		},
		SigningMethod: jwt.SigningMethodRS256,
	})
	jwtMiddleWare = jwtMiddleware
	// Set the router as the default one shipped with Gin
	router := gin.Default()
	router.Use(cors.New(cors.Config{
		AllowMethods:     []string{"POST"},
		AllowHeaders:     []string{"*"},
		ExposeHeaders:    []string{"Content-Length"},
		AllowCredentials: true,
		AllowAllOrigins:  true,
	}))

	router.POST("/does-user-exists", authMiddleware(), controllers.DoesUserExists)
	log.Fatal(router.Run(":8081"))
}

func getPemCert(token *jwt.Token) (string, error) {
	cert := ""
	resp, err := http.Get(os.Getenv("AUTH0_DOMAIN") + ".well-known/jwks.json")
	if err != nil {
		return cert, err
	}
	defer resp.Body.Close()
	var jwks = Jwks{}
	err = json.NewDecoder(resp.Body).Decode(&jwks)
	if err != nil {
		return cert, err
	}
	x5c := jwks.Keys[0].X5c
	for k, v := range x5c {
		if token.Header["kid"] == jwks.Keys[k].Kid {
			cert = "-----BEGIN CERTIFICATE-----\n" + v + "\n-----END CERTIFICATE-----"
		}
	}
	if cert == "" {
		return cert, errors.New("unable to find appropriate key")
	}
	return cert, nil
}

// authMiddleware intercepts the requests, and check for a valid jwt token
func authMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// Get the client secret key
		err := jwtMiddleWare.CheckJWT(c.Writer, c.Request)
		if err != nil {
			// Token not found
			fmt.Println(err)
			c.Abort()
			c.Writer.WriteHeader(http.StatusUnauthorized)
			c.Writer.Write([]byte("Unauthorized"))
			return
		}
	}
}

Note: For the AUTH0_Domain configuration on the backend Go server I used https://domain/, where domain is the Auth0 Domain

Any suggestion would be greatly appreciated.

Hi @atiqulakash,

Welcome to the Auth0 Community!

The first thing I would do is take a look at the token you are receiving. Does it contain the audience you are expecting?

You can use jwt.io to parse the token.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.