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);

  

 

posted @ 2024-12-18 18:37  #青鸟爱吃鱼  阅读(3)  评论(0编辑  收藏  举报