既然您询问了使用 Base64 进行解码的问题,我将重点关注这个问题,而不是 .NET 中 JWT 的语义。这应该会稍微揭开 JWT 令牌的神秘面纱。
请注意,只有上面的 JWT 字符串的第一段是有效的——它转换为 {"alg":"HS256"},而第二段转换为 aA1!——所以为了举例,我将使用来自 http://jwt.io 的默认示例值:
var jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
因此,根据 JWT.io's introduction,JWT 令牌中只有三个段:
假设令牌没有加密,前两个段可以使用普通的 Base64 解码(一旦你将长度填充为四的倍数,就像上面提到的 @Jacob 一样)。最后一段只是一个密码签名;它不包含任何要解码的有意义的编码信息。
因此,显示解码后的 JWT 内容的简单代码 sn-p 可能如下所示:
var decoded = jwt.Split('.')
.Take(2)
.Select(x =>
Encoding.UTF8.GetString(
Convert.FromBase64String(
x.PadRight(x.Length + (x.Length % 4), '='))))
.Aggregate((s1, s2) => s1 + Environment.NewLine + s2);
Console.WriteLine(decoded);
/* Prints:
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
*/
分离所有 lambda 的更简单示例如下所示:
/// <summary>
/// A function to make the Base64 decoding a little less
/// verbose below:
/// </summary>
string Base64Decode(string value)
{
return Encoding.Default.GetString(Convert.FromBase64String(value));
}
// Get the first two segments into an enumerable:
var pieces = jwt.Split('.').Take(2);
// Pad them with equals signs to a length that is a multiple of four:
var paddedPieces = pieces.Select(x => x.PadRight(x.Length + (x.Length % 4), '='));
// Base64 decode the pieces:
var decodedPieces = paddedPieces.Select(x => Base64Decode(x));
// Join it all back into one string with .Aggregate:
Console.WriteLine(decodedPieces.Aggregate((s1, s2) => s1 + Environment.NewLine + s2));
这里的结果和上面的一样。
当然,如果你打算做有意义的 JWT 操作,比如签名和验证,你应该使用 System.IdentityModel.Tokens.Jwt 中的 JwtSecurityToken 类。但是如果你只需要找出一个未加密的令牌包含哪些信息,就和上面一样简单。