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.