4

I am using Golang and the Gin framework to get claims from a JWT sent from a client. But I can't compare the extracted roles with a string.

When I try to get the value, it returns [test-app] but actually I want the value as "test-app"

token, _, err := new(jwt.Parser).ParseUnverified(tokenString, jwt.MapClaims{})
if err != nil {
    fmt.Println(err2)
    return
}

if claims, ok := token.Claims.(jwt.MapClaims); ok {
   chkRoles := claims["roles"]

   if chkRoles == "test-app" {
        fmt.Println("Check Roles passed")
   }
} 

and My Payload

    {
        "roles": [
            "test-app"
        ],
        "exp": 1811749673,
        "client_id": "testapp"
    }

How can I get the value from json claims and use it to compare/validate with a string?

Grokify
  • 15,092
  • 6
  • 60
  • 81
Neung K
  • 43
  • 1
  • 3

1 Answers1

4

The rolesclaim in the JWT payload is an array, so it could also contain multiple values, e.g. "roles":["test-app", "production-app"]

chkRoles is therefore a slice containing these values. You could access them by index, e.g. chkRoles[0], but if you don't know in which position you would find the value you're looking for, you can iterate over the slice like this:

chkRoles := claims["roles"].([]interface{})
for _, role:=range chkRoles {
  if role == "test-app" {
    fmt.Println("Check Roles passed")
    break
  }
}

With this code you'll find out, if the rolesclaim contains the value "test-app".

Here's a complete program:

package main

import (
    "fmt"
    "github.com/dgrijalva/jwt-go"   
)

func main() {
    tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJyb2xlcyI6WyJ0ZXN0LWFwcCIsInByb2R1Y3Rpb24tYXBwIl0sImlhdCI6MTUxNjIzOTAyMn0.4VHXYkAXgFkgbQ524ijVClPVJb0GuXRtAVNp3yuGwvA"

    token, _, err := new(jwt.Parser).ParseUnverified(tokenString, jwt.MapClaims{})
    if err != nil {
        fmt.Println(err)
        return
    }

    if claims, ok := token.Claims.(jwt.MapClaims); ok {

        chkRoles := claims["roles"].([]interface{})

        for _, role := range chkRoles {
            if role == "test-app" {
                fmt.Println("Check Roles passed")
                break
            }
        }
    }
}

A full working example can be seen and tested on the Go Playground

jps
  • 20,041
  • 15
  • 75
  • 79
  • Could you explain or link to the documentation for how this works: `.([]interface{})`? Thank you for your answer. – orpheus Mar 06 '22 at 01:41