Files
upstream-centrifugo/internal/cli/checktoken.go
upstream-mirror b352a9a30d
Some checks failed
test / Lint (push) Failing after 3s
test / Test with Go 1.26.8 (push) Failing after 2s
snapshot of https://github.com/centrifugal/centrifugo.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:17:21 +05:00

89 lines
2.5 KiB
Go

package cli
import (
"encoding/json"
"fmt"
"os"
"github.com/centrifugal/centrifugo/v6/internal/config"
"github.com/centrifugal/centrifugo/v6/internal/confighelpers"
"github.com/centrifugal/centrifugo/v6/internal/jwtverify"
"github.com/cristalhq/jwt/v5"
"github.com/spf13/cobra"
)
func CheckToken() *cobra.Command {
var checkTokenConfigFile string
var checkTokenCmd = &cobra.Command{
Use: "checktoken [TOKEN]",
Short: "Check connection JWT",
Long: `Check connection JWT`,
Run: func(cmd *cobra.Command, args []string) {
checkToken(cmd, checkTokenConfigFile, args)
},
}
checkTokenCmd.Flags().StringVarP(&checkTokenConfigFile, "config", "c", "config.json", "path to config file")
return checkTokenCmd
}
func checkToken(cmd *cobra.Command, checkTokenConfigFile string, args []string) {
cfg, _, err := config.GetConfig(cmd, checkTokenConfigFile)
if err != nil {
fmt.Printf("error getting config: %v\n", err)
os.Exit(1)
}
verifierConfig, err := confighelpers.MakeVerifierConfig(cfg.Client.Token)
if err != nil {
fmt.Printf("error: %v\n", err)
os.Exit(1)
}
if len(args) != 1 {
fmt.Printf("error: provide token to check [centrifugo checktoken <TOKEN>]\n")
os.Exit(1)
}
subject, claims, err := parseAndVerifyToken(verifierConfig, cfg, args[0])
if err != nil {
fmt.Printf("error: %v\n", err)
os.Exit(1)
}
var user = fmt.Sprintf("user %s", subject)
if subject == "" {
user = "anonymous user"
}
fmt.Printf("valid token for %s\npayload: %s\n", user, string(claims))
}
// parseAndVerifyToken checks JWT for user.
func parseAndVerifyToken(config jwtverify.VerifierConfig, ruleConfig config.Config, t string) (string, []byte, error) {
token, err := jwt.ParseNoVerify([]byte(t)) // Will be verified later.
if err != nil {
return "", nil, err
}
claims := &jwt.RegisteredClaims{}
err = json.Unmarshal(token.Claims(), claims)
if err != nil {
return "", nil, err
}
ct, err := verify(config, ruleConfig, t)
if err != nil {
return "", nil, fmt.Errorf("token with algorithm %s and claims %s has error: %v", token.Header().Algorithm, string(token.Claims()), err)
}
return ct.UserID, token.Claims(), nil
}
func verify(verifierConf jwtverify.VerifierConfig, cfg config.Config, token string) (jwtverify.ConnectToken, error) {
cfgContainer, err := config.NewContainer(cfg)
if err != nil {
return jwtverify.ConnectToken{}, err
}
verifier, err := jwtverify.NewTokenVerifierJWT(verifierConf, cfgContainer)
if err != nil {
return jwtverify.ConnectToken{}, err
}
return verifier.VerifyConnectToken(token, false)
}