日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WebApi用户登录验证及服务器端用户状态存取

發布時間:2025/3/18 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WebApi用户登录验证及服务器端用户状态存取 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ?最近項目需要給手機端提供數據,采用WebApi的方式,之前的權限驗證設計不是很好,這次采用的是Basic基礎認證。

1、常見的認證方式

? ?我們知道,asp.net的認證機制有很多種。對于WebApi也不例外,常見的認證方式有

  • FORM身份驗證
  • 集成WINDOWS驗證
  • Basic基礎認證
  • Digest摘要認證

2、Basic基礎認證原理

? ?我們知道,認證的目的在于安全,那么如何能保證安全呢?常用的手段自然是加密。Basic認證也不例外,主要原理就是加密用戶信息,生成票據,每次請求的時候將票據帶過來驗證。這樣說可能有點抽象,我們詳細分解每個步驟:

  • 首先登陸的時候驗證用戶名、密碼,如果登陸成功,則將用戶名、密碼按照一定的規則生成加密的票據信息Ticket,將票據信息返回到前端。
  • 如果登陸成功,前端會收到票據信息,然后跳轉到主界面,并且將票據信息也帶到主界面的ActionResult里面(例如跳轉的url可以這樣寫:/Home/Index?Ticket=Ticket)
  • 在主界面的ActionResult里面通過參數得到票據信息Ticket,然后將Ticket信息保存到ViewBag里面傳到前端。
  • 在主界面的前端,發送Ajax請求的時候將票據信息加入到請求的Head里面,將票據信息隨著請求一起發送到服務端去。
  • 在WebApi服務里面定義一個類,繼承AuthorizeAttribute類,然后重寫父類的OnAuthorization方法,在OnAuthorization方法里面取到當前http請求的Head,從Head里面取到我們前端傳過來的票據信息。解密票據信息,從解密的信息里面得到用戶名和密碼,然后驗證用戶名和密碼是否正確。如果正確,表示驗證通過,否則返回未驗證的請求401。
  • ?這個基本的原理。下面就按照這個原理來看看每一步的代碼如何實現。

    3、Basic基礎認證的代碼示例

    ? ? 創建緩存類,存儲用戶狀態信息CacheManager類

    ?

    public class CacheManager{private static Dictionary<String, Object> cache = null;private static CacheManager cacheManager =null;/// <summary>/// 程序運行時,創建一個靜態只讀的進程輔助對象/// </summary>private static readonly object _object = new object();/// <summary>/// Make sure the class is singleton so only one instance is shared by all. /// </summary>private CacheManager(){cache = new Dictionary<string, object>();}/// <summary>/// Get the singleton instance./// </summary>/// <returns></returns>public static CacheManager instance(){//先判斷實例是否存在,不存在再加鎖處理if (cacheManager == null){//在同一時刻加了鎖的那部分程序只有一個線程可以進入,lock (_object){//如實例不存在,則New一個新實例,否則返回已有實例if (cacheManager == null){cacheManager = new CacheManager();}}}return cacheManager;}/// <summary>/// 添加用戶信息/// </summary>/// <param name="key"></param>/// <param name="value"></param>public void add(String key, Object value){if (!cache.ContainsKey(key))cache.Add(key, value);else{remove(key);cache.Add(key, value);}}/// <summary>/// 刪除用戶狀態信息/// </summary>/// <param name="key"></param>public void remove(String key){cache.Remove(key);}/// <summary>/// 初使化緩存/// </summary>public void invalidateCache(){cache = new Dictionary<string, object>();}/// <summary>/// 獲取用戶狀態信息/// </summary>/// <param name="key"></param>/// <returns></returns>public object get(String key){Object obj;if (cache.ContainsKey(key))cache.TryGetValue(key,out obj);else{obj = null;}return obj;}}

      在App_Start文件下創建票據認識類RequestAuthorizeAttribute

    ?

    public class RequestAuthorizeAttribute : AuthorizeAttribute{CacheManager cache = CacheManager.instance();//重寫基類的驗證方式,加入我們自定義的Ticket驗證public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext){//從http請求的頭里面獲取身份驗證信息,驗證是否是請求發起方的ticketvar authorization = actionContext.Request.Headers.Authorization;if ((authorization != null) && (authorization.Parameter != null)){//解密用戶ticket,并校驗用戶名密碼是否匹配var encryptTicket = authorization.Parameter;if (ValidateTicket(encryptTicket)){base.IsAuthorized(actionContext);}else{HandleUnauthorizedRequest(actionContext);}}//如果取不到身份驗證信息,并且不允許匿名訪問,則返回未驗證401else{var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);if (isAnonymous) base.OnAuthorization(actionContext);else HandleUnauthorizedRequest(actionContext);}}//校驗用戶名密碼private bool ValidateTicket(string encryptTicket){//解密Ticketvar strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;//從Ticket里面獲取用戶名和密碼var index = strTicket.IndexOf("&");string strUser = strTicket.Substring(0, index);string strPwd = strTicket.Substring(index + 1);//服務器端判斷用戶信息object objUmodel = cache.get(strUser);if (objUmodel != null){UserModel u = (UserModel)objUmodel;if (u.UserPwd.Equals(strPwd))return true;elsecache.remove(strUser);return false;}else{return false;}}}

      

        在公共方法中創建獲取票據方法

    /// <summary>/// 獲取票據/// </summary>/// <param name="ticketName">票證名稱</param>/// <param name="timeState">票證過期時間</param>/// <param name="userData">票證數據</param>/// <returns></returns>public static FormsAuthenticationTicket GetTicket(string ticketName, int timeState, string userData){FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, ticketName, DateTime.Now,DateTime.Now.AddMinutes(timeState),true, string.Format("{0}&{1}", ticketName, userData),FormsAuthentication.FormsCookiePath);return ticket;}

        用戶登錄時,存入票據

         [HttpPost][AllowAnonymous]public object UserLogin([FromBody] UserModel model){Int32 sysRole = 0;Message msg = new Message() { Content = "登錄失敗,請重新登錄!" };if (model==null || string.IsNullOrEmpty(model.UserCode) || string.IsNullOrEmpty(model.UserPwd)){msg.Flag = false;return msg;}string EncryptPwd = PasswordUtility.Md5To32(model.UserPwd);var userModel = user.UserModelByLogin(model.UserCode, EncryptPwd, sysRole);if (userModel != null && userModel.ID > 0){msg.Flag = true;msg.Content = "登錄成功!";FormsAuthenticationTicket ticket = Common.GetTicket(userModel.UserCode, timeState, EncryptPwd);//返回登錄結果、用戶信息、用戶驗證票據信息var oUser = new UserModel { Flag = true,UserCode= userModel.UserCode,UserImg= userModel.UserImg, UserName = userModel.UserName, UserPwd = EncryptPwd, Ticket = FormsAuthentication.Encrypt(ticket) };msg.ApiData = oUser;cache.add(model.UserCode, oUser);}else{msg.Flag = false;msg.Data = "";}return msg;}

     ?

    4、WebApi跨域調用方法

    因為WebApi涉及到跨域請求,所以在WebConfig中需要加入一段代碼,解決跨域問題,Authorization是向http的head里面加入請求票據,否則瀏覽器請求不成功。

    <httpProtocol><customHeaders><add name="Access-Control-Allow-Origin" value="*" /><add name="Access-Control-Allow-Headers" value=" Origin,Content-Type, Accept,Authorization" /><add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /></customHeaders></httpProtocol>

      

    5、Web頁面調用WebApi方法,使用Ajax調用方法

    var Ticket;$(function () {$.ajax({type: "post",url: url + "/UserLogin",data: { UserCode: '1002', UserPwd: '123456' },datatype: 'json',success: function (data, status) {if (status == "success") {debugger;if (!data.Flag) {alert("登錄失敗");return;}alert("登錄成功");//登錄成功之后將用戶名和用戶票據帶到主界面Ticket = data.ApiData.Ticket;$("#hdTicket").val(Ticket);}},error: function (e) {},complete: function () {}});});function myfunction() {$.ajax({type: "get",url: url + '/GetLoginOut?uid=1002',datatype:'json',beforeSend: function (request) {alert('beforesend:' + Ticket);//發送ajax請求之前向http的head里面加入驗證信息request.setRequestHeader('Authorization', 'BasicAuth ' + Ticket);},//xhrFields: {// withCredentials: true//},//crossDomain: true,success: function (data) {alert('success:' + data);},error: function (data) {console.log(data);alert('error:' + data);}});}

      

    ? ?跨域請求參考地址:https://www.cnblogs.com/cdemo/p/5158663.html

    ? 原為參考地址:https://www.cnblogs.com/landeanfen/p/5287064.html

    轉載于:https://www.cnblogs.com/personblog/p/8535204.html

    總結

    以上是生活随笔為你收集整理的WebApi用户登录验证及服务器端用户状态存取的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。