C# 自定义JWT 仿写认证
1、系统已经有了JWT了,认证冲突。
public class MyJwt { private const string SecretKey = "YourSecretKeyHere"; // 创建类似JWT的令牌 public static string CreateToken(List<Claim> claims) { var header = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}"; var headerBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(header)); var payload = "{"; foreach (var claim in claims) { payload += $"\"{claim.Type}\":\"{claim.Value}\","; } payload = payload.TrimEnd(','); payload += "}"; var payloadBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(payload)); var dataToSign = $"{headerBase64}.{payloadBase64}"; using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(SecretKey))) { var signature = hmac.ComputeHash(Encoding.UTF8.GetBytes(dataToSign)); var signatureBase64 = Convert.ToBase64String(signature); return $"{headerBase64}.{payloadBase64}.{signatureBase64}"; } } // 验证类似JWT的令牌 public static string ValidateToken(string token) { if (string.IsNullOrEmpty(token)) { return "请传入Tocken"; } var parts = token.Split('.'); if (parts.Length != 3) { return "Tocken长度不正确"; } var headerBase64 = parts[0]; var payloadBase64 = parts[1]; var signatureBase64 = parts[2]; var dataToSign = $"{headerBase64}.{payloadBase64}"; using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(SecretKey))) { var newSignature = hmac.ComputeHash(Encoding.UTF8.GetBytes(dataToSign)); var newSignatureBase64 = Convert.ToBase64String(newSignature); if (newSignatureBase64 != signatureBase64) { return "Tocken字节异常"; } } // 解析负载,检查声明 string payloadJson = Encoding.UTF8.GetString(Convert.FromBase64String(payloadBase64)); if (!payloadJson.Contains("exp")) { return "Tocken时间字节异常"; } var jsonDocument = JsonDocument.Parse(payloadJson); var root = jsonDocument.RootElement; if (root.TryGetProperty("exp", out var expProperty)) { string expValue = expProperty.GetString(); // 将字符串时间转换为DateTime类型(这里以UTC时间为例) if (DateTime.TryParse(expValue, out var expirationTime)) { if(expirationTime < DateTime.Now) { return "Tocken已过期"; } } } return "OK"; } } // 表示JWT风格令牌中的声明 public class Claim { public string Type { get; set; } public string Value { get; set; } } // 表示JWT风格的令牌 public class MyJwtToken { public string Header { get; set; } public string Payload { get; set; } public string Signature { get; set; } }
调用方式
var claims = new List<Claim> { new Claim { Type = "appId", Value = appId }, new Claim { Type = "secret", Value = secret }, new Claim { Type = "exp", Value = expirationTimeString } }; var tocken = MyJwt.CreateToken(claims); // 校验 string isValid = MyJwt.ValidateToken(tocken);