简体   繁体   English

解析 JWT 令牌以获取有效负载内容,无需 C# 或 Blazor 中的外部库

[英]Parse JWT Token to get the payload content only without external library in C# or Blazor

I am writing the client app with Blazor that has access to a JWT.我正在使用可以访问 JWT 的 Blazor 编写客户端应用程序。 I'd like to know a simple way to read the token payload content without adding additional dependency because I don't need the other information and don't need to validate the token.我想知道一种无需添加额外依赖项即可读取令牌有效负载内容的简单方法,因为我不需要其他信息并且不需要验证令牌。 I think parsing the payload content should be simple enough to just write it in a method.我认为解析有效负载内容应该足够简单,只需将其写入方法即可。

    JwtTokenContent ReadJwtTokenContent(string token)
    {
        var content = token.Split('.')[1];

        // Exception here, it's not a valid base64 string
        var jsonPayload = Encoding.UTF8.GetString(
            Convert.FromBase64String(content));

        Console.WriteLine(jsonPayload);

        return JsonSerializer.Deserialize<JwtTokenContent>(jsonPayload);
    }

How can I decode the payload?如何解码有效载荷? It doesn't seem to be just a base64 string.它似乎不仅仅是一个 base64 字符串。

The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.输入不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字符或填充字符中的非法字符。

This is an example JWT token:这是一个示例 JWT 令牌:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6IjUyYjg3ZTUwLTViYmMtNDE0Ny1iOTMwLWY2ZGI0ZTUyNDEwYiIsIlVzZXJuYW1lIjoiZGF0dm1Ab3V0bG9vay5jb20iLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo0NDMyMi8ifQ.4wKxDCwQ6onvNA_atndSitGjufR-tXutWq-tRNhqKzc eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6IjUyYjg3ZTUwLTViYmMtNDE0Ny1iOTMwLWY2ZGI0ZTUyNDEwYiIsIlVzZXJuYW1lIjoiZGF0dm1Ab3V0bG9vay5jb20iLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo0NDMyMi8ifQ.4wKxDCwQ6onvNA_atndSitGjufR-tXutWq-tRNhqKzc

(content is eyJJZCI6IjUyYjg3ZTUwLTViYmMtNDE0Ny1iOTMwLWY2ZGI0ZTUyNDEwYiIsIlVzZXJuYW1lIjoiZGF0dm1Ab3V0bG9vay5jb20iLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo0NDMyMi8ifQ ) (内容是eyJJZCI6IjUyYjg3ZTUwLTViYmMtNDE0Ny1iOTMwLWY2ZGI0ZTUyNDEwYiIsIlVzZXJuYW1lIjoiZGF0dm1Ab3V0bG9vay5jb20iLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo0NDMyMi8ifQ


Thanks to Kalten, here's the solution for my case:感谢 Kalten,这是我的案例的解决方案:

    JwtTokenContent ReadJwtTokenContent(string token)
    {
        var content = token.Split('.')[1];
        Console.WriteLine(content);

        var jsonPayload = Encoding.UTF8.GetString(
            this.Decode(content));
        Console.WriteLine(jsonPayload);

        return JsonSerializer.Deserialize<JwtTokenContent>(jsonPayload);
    }

    byte[] Decode(string input)
    {
        var output = input;
        output = output.Replace('-', '+'); // 62nd char of encoding
        output = output.Replace('_', '/'); // 63rd char of encoding
        switch (output.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: output += "=="; break; // Two pad chars
            case 3: output += "="; break; // One pad char
            default: throw new System.ArgumentOutOfRangeException("input", "Illegal base64url string!");
        }
        var converted = Convert.FromBase64String(output); // Standard base64 decoder
        return converted;
    }

Try this by Steve Anderson史蒂夫安德森试试这个

 public static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
    {
        var payload = jwt.Split('.')[1];
        var jsonBytes = ParseBase64WithoutPadding(payload);
        var keyValuePairs = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonBytes);
        return keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString()));
    }

    private static byte[] ParseBase64WithoutPadding(string base64)
    {
        switch (base64.Length % 4)
        {
            case 2: base64 += "=="; break;
            case 3: base64 += "="; break;
        }
        return Convert.FromBase64String(base64);
    }

Usage用法

var token = await GetTokenAsync();
        var identity = string.IsNullOrEmpty(token)
            ? new ClaimsIdentity()
            : new ClaimsIdentity(ServiceExtensions.ParseClaimsFromJwt(token), "jwt");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM