WebApi基于Token和签名的验证

时间:2022-01-03 06:07:57

最近一段时间在学习WebApi,涉及到验证部分的一些知识觉得自己并不是太懂,所以来博客园看了几篇博文,发现一篇讲的特别好的,读了几遍茅塞顿开(都闪开,我要装逼了),刚开始读有些地方不理解,所以想了很久,因此对原文中省略的部分这里做一点个人的理解和补充,非常基础,知道的园友就不需要了,只是帮助初次学习的园友理解。原文传送门:

本篇博文中的所有代码均来自上述链接,如果你觉得有帮助,请点击链接给原文大牛一个推荐,开搞!!

1.基于Token令牌 + 签名的验证思路梳理

    客户端首先向服务端请求Token令牌,客户获取Token后计算对应的签名。签名由时间戳、随机数、Token令牌、参数拼接字符串四部分组成,客户端发送请求的时候需要带上对应的身份ID、时间戳、随机数和计算出的签名。

    服务端过滤器拦截请求,验证请求参数的合法性、是否过期,Token令牌是否合法、是否过期,全部通过后重新计算签名,与传递的签名参数对比,一致则执行对应的Api请求,否则返回错误消息。如果服务端计算的签名与传递的参数签名不一样,请求不合法(可能被篡改),为什么这么说呢,因为客户端与服务端拥有相同的签名计算方式,如果请求被修改,那么服务端计算的签名肯定与客户端计算的签名肯定不一致。

 

1.1 客户端请求Token令牌流程

    客户端请求Token的凭证是对应的身份ID,当然可以是其他的,这里假设用的是身份ID。

    (1)首先客户端向服务端发送获取Token令牌的请求,这个Token令牌是一个GUID码,生成后服务端会将其存在缓存中,当再次请求的时候会先从缓存中查找。请求Token令牌的代码:

public static ProductResultMsg.TokenResultMsg GetSignToken(int staffId) { string tokenApi = AppSettingsConfig.GetTokenApi; Dictionary<string, string> parames = new Dictionary<string, string>(); parames.Add("staffid", staffId.ToString()); Tuple<string, string> parameters = GetQueryString(parames); ProductResultMsg.TokenResultMsg token = WebApiHelper.Get<ProductResultMsg.TokenResultMsg> (tokenApi, parameters.Item1, staffId.ToString(), staffId, false); return token; }

 

代码解释:

1.tokenApi是配置在webConfig中的接口Url

2.Parames字典对象用来封装参数的,因为请求Token时可能不止一个参数。

3.Parameter:是元组类型,元组可以承载任何的数据类型,这里用来接收GetQueryString方法返回的拼接字符串

4.token:客户端用来承载接口返回的Token令牌的类的实例,TokenResultMSg结构如下:

public class TokenResultMsg : HttpResponseMsg { public Tokens Result { get { if (StatusCode == (int)StatusCodeEnum.Success) { return JsonConvert.DeserializeObject<Tokens>(Data.ToString()); } return null; } } }

    可以看到这个类实际是封装了一个Token类实例,因为Api接口返回的是Json数据类型,所以这里进行了反序列化。Token类结构在最上面,里面包含身份IDToken令牌、 过期时间三个属性,最后返回包含Token令牌的Token类给主程序。Token类结构如下:

public class Tokens { /// <summary> /// 用户名 /// </summary> public int StaffId { get; set; } /// <summary> /// 用户名对应签名Token /// </summary> public Guid SignToken { get; set; } /// <summary> /// Token过期时间 /// </summary> public DateTime ExpireTime { get; set; } }

(2)上面调用了GetQueryString方法,这个方法是用来整理参数以及参数的拼接字符串,参数用来随URL传递,参数的拼接字符串用来生成对应的Sign签名,方法如下: