Web APIs 基於令牌TOKEN驗證的實現
概述:
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緩存。實現如下:

2. 新建ApiAuthorizeAttribute類,繼承AuthorizeAttribute,重寫方法IsAuthorized,這樣基於TOKEN驗證方式就完成了。實現如下:

3. 登錄實現

4. 測試API
這樣就可以配合.NET原有的 AllowAnonymousAttribute 屬性使用, 使用方法如下:
不需要驗證身份的 類或者Action 添加 [AllowAnonymous]屬性,否則添加[ApiAuthorize]
1 /// <summary> 2 /// 測試 3 /// </summary> 4 [ApiAuthorize] 5 public class TestController : BaseApiController 6 { 7 /// <summary> 8 /// 測試權限1 9 /// </summary> 10 [HttpGet] 11 public string TestAuthorize1() 12 { 13 return "TestAuthorize1"; 14 } 15 /// <summary> 16 /// 測試權限2 17 /// </summary> 18 [AllowAnonymous] 19 [HttpGet] 20 public string TestAuthorize2() 21 { 22 return "TestAuthorize2"; 23 } 24 }
測試一:
1 //TestAuthorize 2 function TestAuthorize1() { 3 $.ajax({ 4 type: "get", 5 url: host + "/mobileapi/test/TestAuthorize1", 6 dataType: "text", 7 data: {}, 8 beforeSend: function (request) { 9 request.setRequestHeader("token", $("#token").val()); // 請求發起前在頭部附加token 10 }, 11 success: function (data) { 12 alert(data); 13 }, 14 error: function (x, y, z) { 15 alert("報錯無語"); 16 } 17 }); 18 }
結果如下:
測試二:
1 //TestAuthorize 2 function TestAuthorize2() { 3 $.ajax({ 4 type: "get", 5 url: host + "/mobileapi/test/TestAuthorize2", 6 dataType: "text", 7 data: {}, 8 beforeSend: function (request) { 9 request.setRequestHeader("token", $("#token").val()); // 請求發起前在頭部附加token 10 }, 11 success: function (data) { 12 alert(data); 13 }, 14 error: function (x, y, z) { 15 alert("報錯無語"); 16 } 17 }); 18 }
結果如下:
測試三:
1 //TestAuthorize 2 function TestAuthorize1() { 3 $.ajax({ 4 type: "get", 5 url: host + "/mobileapi/test/TestAuthorize1", 6 dataType: "text", 7 data: {}, 8 beforeSend: function (request) { 9 //request.setRequestHeader("token", $("#token").val()); // 請求發起前在頭部附加token 10 }, 11 success: function (data) { 12 alert(data); 13 }, 14 error: function (x, y, z) { 15 alert("報錯無語"); 16 } 17 }); 18 }
結果如下:
測試四:
1 //TestAuthorize 2 function TestAuthorize2() { 3 $.ajax({ 4 type: "get", 5 url: host + "/mobileapi/test/TestAuthorize2", 6 dataType: "text", 7 data: {}, 8 beforeSend: function (request) { 9 //request.setRequestHeader("token", $("#token").val()); // 請求發起前在頭部附加token 10 }, 11 success: function (data) { 12 alert(data); 13 }, 14 error: function (x, y, z) { 15 alert("報錯無語"); 16 } 17 }); 18 }
結果如下:
方法二:
此方法缺點就是每次請求都需要附帶token請求參數,這對於有強迫症的程序猿來說是一種折磨,不細說,實現代碼如下,有需要的自己研究研究:
