最近在做的項目得到經驗,在做登錄的時候,使用FormsAuthenticationTicket,
登錄成功以后生成cookia作為登錄態維護,票據作為調用其他接口的憑據,票據生成后傳到前台作為調用接口的憑證,這里有二種情況
一:不在登錄的時候使用cookia,而是根據用戶名和webconfig里面的設置使用cookia作為登錄的時效維護
(1)登錄成功以后
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1,
account,
DateTime.Now,
DateTime.Now.AddHours(12),
true,
JsonConvert.SerializeObject(userData),
FormsAuthentication.FormsCookiePath);
string ticString = FormsAuthentication.Encrypt(ticket);
FormsAuthentication.SetAuthCookie(account, true); //當沒有設置cookies身份驗證的時候,按照webconfig的設置表單驗證,可設置cookia過期時間的滑動
(2)webconfig里面設置
<system.web>
<authentication mode="Forms">
<!--cookia自動滑動十分鍾-->
<forms name=".ASPXAUTH" loginUrl="~/Users/Login" defaultUrl="~/Home/Index" protection="All" timeout="1" path="/" requireSSL="false" slidingExpiration="true" enableCrossAppRedirects="false" cookieless="UseDeviceProfile" domain="" />
</authentication>
<system.web>
name可以自定義,缺省時ASPXAUTH
二: 官方說:FormsAuthenticationTicket的IsPersistent 屬性字段標志 是否為持久化cookie 會話性cookie保存於內存中。關閉瀏覽器則會話性cookie會過期消失;持久化cookie則不會,直至過期時間已到或確認注銷。
但是我試驗的結果是,均不能持久化,均會在設置的過期時間到來的時候便憑據失效
(1)登錄成功以后,根據用戶生成票據,並設置cookia的過期時間,cookia和tict憑據在到期時間都會清空或者失效
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1,
account,
DateTime.Now,
DateTime.Now.AddHours(12),
true,
JsonConvert.SerializeObject(userData),
FormsAuthentication.FormsCookiePath);
string ticString = FormsAuthentication.Encrypt(ticket);
var tict = new HttpCookie(FormsAuthentication.FormsCookieName, ticString);
tict.HttpOnly = true;
if (ticket.IsPersistent) //是否為持久化cookie 會話性cookie保存於內存中。關閉瀏覽器則會話性cookie會過期消失;持久化cookie則不會,直至過期時間已到或確認注銷。
{
tict.Expires = ticket.Expiration; //設置cookie到期時間
}
//把票據信息寫入Cookie和Session
//SetAuthCookie方法用於標識用戶的Identity狀態為true
HttpContext.Current.Response.Cookies.Add(tict); // 若不設置cookia的過期時間,默認關閉瀏覽器(會話)清空cookia,若有設置則按照設置的過期時間
(2)登錄成功以后,根據用戶生成票據,不設置cookia的過期時間,cookia會在關閉瀏覽器(會話)清空cookia清空和tict憑據在到期時間或者失效
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1,
account,
DateTime.Now,
DateTime.Now.AddHours(12),
true,
JsonConvert.SerializeObject(userData),
FormsAuthentication.FormsCookiePath);
string ticString = FormsAuthentication.Encrypt(ticket);
var tict = new HttpCookie(FormsAuthentication.FormsCookieName, ticString);
//把票據信息寫入Cookie和Session
//SetAuthCookie方法用於標識用戶的Identity狀態為true
HttpContext.Current.Response.Cookies.Add(tict); // 若不設置cookia的過期時間,默認關閉瀏覽器(會話)清空cookia,若有設置則按照設置的過期時間
在接口過濾器里面,首先判斷登錄是否過期,沒過期的話則獲取前台調用接口時的header,進行解密,獲取用戶的數據和權限等賬號信息,別人系統有三種用戶類型,也放到這個過濾器里面判斷處理並根據接口的需求修改接口的參數
public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
var userCookia = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (userCookia != null)
{
var auther = actionContext.Request.Headers.Authorization;
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
{
return;
}
if (auther == null)
{
//actionContext.Response.ReasonPhrase = "登錄已過期,請重新登錄";
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,
new {messages = "登錄票據已過期,請重新登錄獲取", resultCode = 1});
//HttpContext.Current.Response.Redirect("~/Views/Home/Index.cshtml"); //跳到登陸頁面
}
else
{
if (auther.Scheme == "Basic" && !string.IsNullOrEmpty(auther.Parameter))
{
var userData = Functions.JudgeSession(auther.Parameter.Trim());
if (userData == null)
{
//actionContext.Response.ReasonPhrase = "登錄已過期,請重新登錄";
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,
new { messages = "登錄票據已過期,請重新登錄獲取", resultCode = 1 });
// HttpContext.Current.Response.Redirect("~/Views/Home/Index.cshtml"); //跳到登陸頁面
}
else
{
actionContext.ActionArguments["account"] = userData.GetValue("account").ToString();
if (!actionContext.ActionArguments.ContainsKey("accountType")) return;
actionContext.ActionArguments["accountType"] = userData.GetValue("accountType").ToString();
if (
!JudgeLoginAccount(userData.GetValue("accountType").ToString(), actionContext,
userData.GetValue("account").ToString()))
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest,
new {messages = "當前登錄賬號不存在", resultCode = 1});
}
}
}
else
{
//actionContext.Response.ReasonPhrase = "登錄已過期,請重新登錄";
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,
new { messages = "登錄票據已過期,請重新登錄獲取", resultCode = 1 });
// HttpContext.Current.Response.Redirect("~/Views/Home/Index.cshtml"); //跳到登陸頁面
}
}
}
else
{
//actionContext.Response.ReasonPhrase = "登錄已過期,請重新登錄";
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,
new { messages = "登錄已過期,請重新登錄", resultCode = 1 });
// HttpContext.Current.Response.Redirect("~/Views/Home/Index.cshtml"); //跳到登陸頁面
}
}
public bool JudgeLoginAccount(string type, HttpActionContext actionContext, string account)
{
var Type = Convert.ToInt32(type);
var requestUrlString = actionContext.Request.RequestUri + "當前登錄用戶不存在用戶不存在";
if (Type == 0) //維保總賬號
{
if (_staffService.LoadEntity(o => o.Account == account && o.ParentID == 0).SingleOrDefault() ==
null)
{
var str = "登錄的維保總賬號不存在";
YYTLog.Record(requestUrlString, str); //寫入日志
return false;
}
}
else if (Type == 1) //維保子賬號
{
if (_staffService.LoadEntity(o => o.Account == account && o.ParentID != 0).SingleOrDefault() ==
null)
{
var str = "登錄的監管人員賬號不存在";
YYTLog.Record(requestUrlString, str); //寫入日志
return false;
}
}
else if (Type == 2) //監管人員
{
if (_supervisorService.LoadEntity(o => o.Account == account).SingleOrDefault() == null)
{
var str = "登錄的監管人員賬號不存在";
YYTLog.Record(requestUrlString, str); //寫入日志
return false;
}
}
else
{
var str = "登錄的監管人員賬號類型有誤";
YYTLog.Record(requestUrlString, str); //寫入日志
return false;
}
return true;
}