概述: 

  ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作。但是在使用API的时候总会遇到跨域请求的问题, 特别各种APP万花齐放的今天,对API使用者身份角色验证是不能避免的(完全开发的API不需要对使用者身份角色进行管控,可以绕过),这篇文章就来谈谈基于令牌TOKEN身份验证的实现。

问题:

   对于Web API的选择性的开放,使用者无论使用AJAX,还是HttpClient对接,总要对使用者的身份角色进行验证,然而使用API总有跨域使用情况的存在,这样就导致所有基于cookie验证方式都不再适用于API的验证。

原因:

  比如,基于form表单验证的基础是登录验证成功后,用户的信息存在缓存或数据库或cookie,无论哪种方式存储用户信息,都不能绕过对cookie的使用,所以form表单验证方法对于禁用cookie的浏览器都不能正常使用,结论就是不能使用cookie 的环境就不能使用基本的form表单验证方式。因此WEB API 由于跨域的使用,导致cookie不能正常工作,所以不能再使用基于表单验证的方式来实现。

基于令牌TOKEN验证方法的实现:

方法一:

     1. 实现对缓存TOKEN的管理,以防IIS服务器的宕机,可以对TOKEN进行持久化存储处理,每次IIS重启重新初始化已经登录成功TOKEN缓存。实现如下:

  1 public class UserTokenManager
  2     {
  3         private static readonly IUserTokenRepository _tokenRep;
  4         private const string TOKENNAME = "PASSPORT.TOKEN";
  5 
  6         static UserTokenManager()
  7         {
  8             _tokenRep = ContainerManager.Resolve<IUserTokenRepository>();
  9         }
 10         /// <summary>
 11         /// 初始化缓存
 12         /// </summary>
 13         private static List<UserToken> InitCache()
 14         {
 15             if (HttpRuntime.Cache[TOKENNAME] == null)
 16             {
 17                 var tokens = _tokenRep.GetAll();
 18                 // cache 的过期时间, 令牌过期时间 *2
 19                 HttpRuntime.Cache.Insert(TOKENNAME, tokens, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromDays(7 * 2));
 20             }
 21             var ts = (List<UserToken>)HttpRuntime.Cache[TOKENNAME];
 22             return ts;
 23         }
 24 
 25 
 26         public static int GetUId(string token)
 27         {
 28             var tokens = InitCache();
 29             var result = 0;
 30             if (tokens.Count > 0)
 31             {
 32                 var id = tokens.Where(c => c.Token == token).Select(c => c.UId).FirstOrDefault();
 33                 if (id != null)
 34                     result = id.Value;
 35             }
 36             return result;
 37         }
 38 
 39 
 40         public static string GetPermission(string token)
 41         {
 42             var tokens = InitCache();
 43             if (tokens.Count == 0)
 44                 return "NoAuthorize";
 45             else
 46                 return tokens.Where(c => c.Token == token).Select(c => c.Permission).FirstOrDefault();
 47         }
 48 
 49         public static string GetUserType(string token)
 50         {
 51             var tokens = InitCache();
 52             if (tokens.Count == 0)
 53                 return "";
 54             else
 55                 return tokens.Where(c => c.Token == token).Select(c => c.UserType).FirstOrDefault();
 56         }
 57 
 58         /// <summary>
 59         /// 判断令牌是否存在
 60         /// </summary>
 61         /// <param name="token"></param>
 62         /// <returns></returns>
 63         public static bool IsExistToken(string token)
 64         {
 65             var tokens = InitCache();
 66             if (tokens.Count == 0) return false;
 67             else
 68             {
 69                 var t = tokens.Where(c => c.Token == token).FirstOrDefault();
 70                 if (t == null)
 71                     return false;
 72                 else if (t.Timeout < DateTime.Now)
 73                 {
 74                     RemoveToken(t);
 75                     return false;
 76                 }
 77                 else
 78                 {
 79                     // 小于8小时 更新过期时间
 80                     if ((t.Timeout - DateTime.Now).TotalMinutes < 1 * 60 - 1)
 81                     {
 82                         t.Timeout = DateTime.Now.AddHours(8);
 83                         UpdateToken(t);
 84                     }
 85                     return true;
 86                 }
 87 
 88             }
 89         }
 90 
 91         /// <summary>
 92         /// 添加令牌, 没有则添加,有则更新
 93         /// </summary>
 94         /// <param name="token"></param>
 95         public static void AddToken(UserToken token)
 96         {
 97             var tokens = InitCache();
 98             // 不存在  怎增加
 99             if (!IsExistToken(token.Token))
100             {
101                 token.ID = 0;
102                 tokens.Add(token);
103                 // 插入数据库
104                 _tokenRep.Add(token);
105             }
106             else  // 有则更新
107             {
108                 UpdateToken(token);
109             }
110         }
111 
112         public static bool UpdateToken(UserToken token)
113         {
114             var tokens = InitCache();
115             if (tokens.Count == 0) return false;
116             else
117             {
118                 var t = tokens.Where(c => c.Token == token.Token).FirstOrDefault();
119                 if (t == null)
120                     return false;
121                 t.Timeout = token.Timeout;
122                 // 更新数据库
123                 var tt = _tokenRep.FindByToken(token.Token);
124                 if (tt != null)
125                 {
126                     tt.UserType = token.UserType;
127                     tt.UId = token.UId;
128                     tt.Permission = token.Permission;
129                     tt.Timeout = token.Timeout;
130                     _tokenRep.Update(tt);
131                 }
132                 return true;
133             }
134         }
135         /// <summary>
136         /// 移除指定令牌
137         /// </summary>
138         /// <param name="token"></param>
139         /// <returns></returns>
140         public static void RemoveToken(UserToken token)
141         {
142             var tokens = InitCache();
143             if (tokens.Count == 0) return;
144             tokens.Remove(token);
145             _tokenRep.Remove(token);
146         }
147 
148         public static void RemoveToken(string token)
149         {
150             var tokens = InitCache();
151             if (tokens.Count == 0) return;
152 
153             var ts = tokens.Where(c => c.Token == token).ToList();
154             foreach (var t in ts)
155             {
156                 tokens.Remove(t);
157                 var tt = _tokenRep.FindByToken(t.Token);
158                 if (tt != null)
159                     _tokenRep.Remove(tt);
160             }
161         }
162 
163 
164         public static void RemoveToken(int uid)
165         {
166             var tokens = InitCache();
167             if (tokens.Count == 0) return;
168 
169             var ts = tokens.Where(c => c.UId == uid).ToList();
170             foreach (var t in ts)
171             {
172                 tokens.Remove(t);
173                 var tt = _tokenRep.FindByToken(t.Token);
174                 if (tt != null)
175                     _tokenRep.Remove(tt);
176             }
177         }
178     }
View Code

相关文章:

  • 2022-12-23
  • 2021-05-17
  • 2022-12-23
  • 2022-12-23
  • 2021-12-15
  • 2021-11-07
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-09-14
  • 2021-12-15
  • 2021-07-21
相关资源
相似解决方案