【问题标题】:Could not decode JWT payload from base64无法从 base64 解码 JWT 有效负载
【发布时间】:2020-09-18 12:48:23
【问题描述】:

我要从请求头中解码一个 JWT 令牌,它看起来像这样:

eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIsImlzcyI6ImxvY2FsaG9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWlAZ21haWwuY29tIn0 P>

public static string Base64Decode(string base64EncodedData)
{
    var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
    return Encoding.UTF8.GetString(base64EncodedBytes);
}

当将上面的令牌传递给解码方法时,它会抛出一个异常,告诉:

Base-64 字符数组或字符串的长度无效

dotnetfiddle 参考:https://dotnetfiddle.net/Z2TUz9

但是在 javascript 中使用时(使用 atob 函数),它可以正常工作。

谁能告诉我为什么,然后告诉我如何在 C# 中对其进行解码?

【问题讨论】:

  • 看起来你去掉了字符串末尾的“==”。保持打开状态。
  • 不,字符串末尾没有“==”,使用javascript的解码功能可以正常工作。只是 C# 代码不起作用

标签: c# jwt base64 base64url


【解决方案1】:

在我详细讨论这个问题之前,我通常建议使用JWT library,它可以通过几个函数调用完成所有需要完成的工作。

作为Base64字符串,确实太短了。有效的 Base64 编码字符串的长度应可被 4 整除,如有必要,应使用 1 或 2 个填充字符 = 填充。但 JWT 使用的 Base64url 编码略有不同,在这种编码中填充是可选的。

但 C# Base64 解码器在这方面相当严格。 因此,您需要将 Base64Url 转换为 Base64 并添加缺少的填充。除此之外,还有两个Base64Url特有的字符需要转回Base64,如下代码所示:

using System;
                    
public class Program
{
    public static void Main()
    {
        string token = "eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIsImlzcyI6ImxvY2FsaG9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWlAZ21haWwuY29tIn0";
        token = token.Replace('_', '/').Replace('-', '+');
        switch (token.Length % 4)
        {
            case 2: token += "=="; break;
            case 3: token += "="; break;
        }       
        var decoded = Convert.FromBase64String(token);
        var decodedToken = System.Text.Encoding.Default.GetString(decoded);     
        Console.WriteLine(decodedToken);
    }
}

Code in dotnetfiddle

decoded 的数据类型是byte[],输出只是类型的名称。要将其转换为字符串并打印 JSON,我添加了另一行。

从这里开始的下一步是将 JSON 转换为 C# 对象或使用开头提到的库。

【讨论】:

    猜你喜欢
    • 2018-08-06
    • 2017-08-21
    • 2020-04-12
    • 2016-05-29
    • 2018-03-17
    • 2017-01-06
    • 2020-01-07
    • 1970-01-01
    • 2016-03-12
    相关资源
    最近更新 更多