三 Web API 授權方式
web api的客戶端,包括 android,ios,h5,自然對訪問許可權要加上授權機制。對於h5,要求把h5站點和web api部署在同一個域名下,然後對web api 配置為禁止跨域訪問。而對 android 和 ios 等app端訪問,則參考微信的簽名驗證方式,在請求url後面加上
時間戳,隨機字串,以及加密後的簽名。下面主要就app端授權實現程式碼說明一下。
1 首先 定義一個 KEY,隨便自己定義,我這裡直接取一個guid,你可以存放在資料庫,也可以存config檔案,也可以直接在程式碼裡 const定義。我這裡放在config。
<appSettings> <add key="AppKey" value="254d-4eaa-85f4-a92ff4c08042" /> </appSettings>
2 實現一個特性類,繼承自.net自帶的AuthorizationFilterAttribute。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class ApiAuthFilterAttribute : AuthorizationFilterAttribute { 。。。。 }
AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)的意思 很容易理解,即當前訪問授權驗證可以用在整個controller(class),也可以用在某個web api(method)上。
這個類裡面,重點是過載 OnAuthorization方法。方法裡的actionContext引數是一個微軟針對api請求的做了一些封裝改進的一個請求上下文,裡面包含了api 請求引數等資訊,可惜缺乏我想要的header裡的引數。
我們和app端約定把授權相關引數放在header裡面,還有後面一些有關api版本的引數等都放在header裡,放在header裡安全性更高一些,而且對於app端封裝http請求也更簡單。為了從actionContext得到普通的HttpContext物件,
轉換程式碼:HttpRequestBase request = (actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase).Request;
public override void OnAuthorization(HttpActionContext actionContext) { base.OnAuthorization(actionContext); // 允許匿名訪問 if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0) { return; } HttpRequestBase request = (actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase).Request;
拿到了request,可以通過
string signature = request.Headers["signature"]; string timestamp = request.Headers["timestamp"];
string nonce = request.Headers["nonce"];
result = CheckSignature(signature, timestamp, nonce);
進行授權驗證
對於需要進行授權的web api
[HttpGet] [ApiAuthFilter] public ApiResult GetShopQRCodeList() { 。。。 }
3 對於使用者身份識別,我們使用了token機制。即使用者登入成功後分配一個token(採用guid)給到客戶端。當客戶端在請求的header裡攜帶了token時,我們就可以根據token識別當前請求的使用者。在資料庫裡設計了token表,記錄使用者登入時間,登入裝置(h5,app,微信公眾號等),token值等,相當於cookie,用於控制使用者免密碼登入,以及可以同時登入幾種裝置等。