无法从 base64 解码 JWT 负载
Could not decode JWT payload from base64
我要从请求 header 中解码 JWT 令牌,它看起来像这样:
eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIsImlzcyI6ImxvY2FsaG9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWlAZ21haWwuY29tIn0
public static string Base64Decode(string base64EncodedData)
{
var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
return Encoding.UTF8.GetString(base64EncodedBytes);
}
将上面的令牌传递给 decode 方法时,它抛出一个异常告诉:
Invalid length for a Base-64 char array or string
dotnetfiddle 参考:https://dotnetfiddle.net/Z2TUz9
但是在javascript中使用时(使用atob函数),可以正常使用。
谁能告诉我为什么,然后告诉我如何用 C# 解码它?
在详细讨论这个问题之前,我通常建议使用 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);
}
}
解码的数据类型是byte[]
,输出只是类型的名称。要将其转换为字符串并打印 JSON 我添加了另一行。
从这里开始的下一步是将 JSON 转换为 C# 对象或使用开头提到的库。
我要从请求 header 中解码 JWT 令牌,它看起来像这样:
eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIsImlzcyI6ImxvY2FsaG9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWlAZ21haWwuY29tIn0
public static string Base64Decode(string base64EncodedData)
{
var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
return Encoding.UTF8.GetString(base64EncodedBytes);
}
将上面的令牌传递给 decode 方法时,它抛出一个异常告诉:
Invalid length for a Base-64 char array or string
dotnetfiddle 参考:https://dotnetfiddle.net/Z2TUz9
但是在javascript中使用时(使用atob函数),可以正常使用。
谁能告诉我为什么,然后告诉我如何用 C# 解码它?
在详细讨论这个问题之前,我通常建议使用 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);
}
}
解码的数据类型是byte[]
,输出只是类型的名称。要将其转换为字符串并打印 JSON 我添加了另一行。
从这里开始的下一步是将 JSON 转换为 C# 对象或使用开头提到的库。