目前使用的 .NETframework 4.7.2
没有去配session,有的说roken验证不配session,但是看网上也有说要配session的,退出接口怎么写?是一个疑问(token是配在请求头里面的,所以后端怎么操作清除?)
/// <summary>
/// 登录
/// </summary>
/// <param name="loginModel"></param>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
public IHttpActionResult Login([FromBody] LoginModel loginModel)
{
S_DoctorsUser user = null;
string QueueVersion = null;
string psd = md5.GenerateMD5(loginModel.PassWord);
user = baseDLL.GetSingle<S_DoctorsUser>(p => p.Account == loginModel.Account && p.PassWord == psd && p.IsValid == "Valid");
if (user == null)
{
return Json(new { Status = state, data = "", msg = "账号或密码错误" });
}
FormsAuthenticationTicket tokeninfo = new FormsAuthenticationTicket(0, user.Account, DateTime.Now, DateTime.Now.AddMinutes(1), true, $"{user.Account}&{user.PassWord}");
//返回登录结果、用户信息、用户验证票据信息
var token = FormsAuthentication.Encrypt(tokeninfo);
//预约叫号版本号
QueueVersion = System.Configuration.ConfigurationManager.AppSettings["QueueVersion"];
return Json(new { Status = state, data = new { token, user, QueueVersion }, msg = "登录成功!" });
}
其中两个重载方法 31行和59行
31是没有cookie 59是有cookie
cookie由于前端原因没法传过来,所以现在这个项目没有使用到cookie,选择的是31行的重载,59行这个CookiePath字面意思应该就是cookie的路径,测试时候试过,没有用
Expired代表的是否是过期的token,IsPersistent注释写的是是否是能跨站的cookie(有点不太懂。。。)
登陆action加了一个AllowAnonymous特性是指定这个action不用进行验证。也能加在controller上
有继承 AuthorizeAttribute 我看了一下 AuthorizeAttribute是继承AuthorizationFilterAttribute的,我选择的是AuthorizationFilterAttribute
public override void OnAuthorization(HttpActionContext actionContext)
{
//分别验证在method和controller中的AllowAnonymousAttribute属性
if (((ReflectedHttpActionDescriptor)actionContext.ActionDescriptor).MethodInfo.IsDefined(typeof(AllowAnonymousAttribute), true)
|| actionContext.ActionDescriptor.ControllerDescriptor.ControllerType.IsDefined(typeof(AllowAnonymousAttribute), true))
{
return;
}
var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
////获取token(请求头里面的值)
var token = HttpContext.Current.Request.Headers["token"] ?? "";
//是否为空
if (!string.IsNullOrEmpty(token.ToString()))
{
//解密用户ticket,并校验用户名密码是否匹配
if (!ValidateTicket(token.ToString()))
{
HandleUnauthorizedRequest(actionContext);
}
}
//如果取不到身份验证信息,则返回未验证403
else
{
HandleUnauthorizedRequest(actionContext);
}
base.OnAuthorization(actionContext);
}
/// <summary>
/// 校验用户名密码(对数据库数据匹配)
/// </summary>
/// <param name="encryptToken"></param>
/// <returns>返回匹配上的用户</returns>
private bool ValidateTicket(string encryptToken)
{
//解密Ticket(解密不通过会直接抛异常)
var tokeninfo = FormsAuthentication.Decrypt(encryptToken);
if (tokeninfo.Expired)
{
return false;
}
var strTicket = tokeninfo.UserData;
//从Ticket里面获取用户名和密码
var index = strTicket.IndexOf("&");
string userName = strTicket.Substring(0, index);
string password = strTicket.Substring(index + 1);
BaseDLL baseDLL = new BaseDLL();
S_DoctorsUser user = baseDLL.GetSingle<S_DoctorsUser>(s => s.Account == userName && s.PassWord == password && s.IsValid == "Valid");
//解析出来的登陆用户信息存在容器里面以方便使用
HttpContext.Current.Items.Add("user", user);
return true;
}
/// <summary>
/// token验证不通过
/// </summary>
/// <param name="filterContext"></param>
protected void HandleUnauthorizedRequest(HttpActionContext filterContext)
{
var response = filterContext.Response = filterContext.Response ?? new HttpResponseMessage();
//状态码401改为其他状态码来避免被重定向。最合理的是改为403,表示服务器拒绝。
response.StatusCode = HttpStatusCode.Forbidden;
ResponseModel content = new ResponseModel
{
Status = "success",
Data = null,
Msg = "服务端拒绝访问",
};
response.Content = new StringContent(Json.Encode(content), Encoding.UTF8, "application/json");
}
}
原文:https://www.cnblogs.com/RecordOnLog/p/14897149.html