C# 自定义JWT 仿写认证

1、系统已经有了JWT了,认证冲突。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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; }
}

  

调用方式

1
2
3
4
5
6
7
8
9
10
11
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);

  

 

posted @   #青鸟爱吃鱼  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示