我们把登录功能完善,这次我们把用户输入的账号和密码提交到后台。后台判断账号和密码,如果验证通过的,后台就生成Token,验证不通过,返回一个空字符串。前台发现是空字符串就不要写到localstorage里面,注意Token的时间。
public class LoginController : ApiController
{
private string secret = "bamn.cn";
public string Post(dynamic obj)
{
//验证账号和密码 正常来说 这里应该是查找数据库的
if (obj.name != "admin" || obj.password != "123321")
{
return string.Empty;
}
IDateTimeProvider provider = new UtcDateTimeProvider();
var now = provider.GetNow();
var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var secondsSinceEpoch = Math.Round((now - unixEpoch).TotalSeconds);
var payload = new Dictionary<string, object>
{
{"name", obj.name },
{"exp", secondsSinceEpoch + 1000 },
{"jti", "luozhipeng" }
};
Console.WriteLine(secondsSinceEpoch);
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var token = encoder.Encode(payload, secret);
return token;
}
}Code language: HTML, XML (xml)
自定义ajax方法加入token
jQuery.apipost = function (url, data, successfn, errorfn) {
$.ajax({
type: "post",
data: JSON.stringify(data),
url: 'http://localhost:23557' + url,
dataType: "json",
contentType: "application/json",
headers: {
Accept: "application/json; charset=utf-8",
Token: localStorage.getItem("Token")
},
success: function (d) {
successfn(d);
},
error: function (d) {
errorfn(d);
}
});
};Code language: JavaScript (javascript)
后台验证Token的地方
public class TokenAuthAttribute : AuthorizeAttribute
{
private string secret = "bamn.cn";
//重写基类的验证方式,加入我们自定义的Ticket验证
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//url获取token
var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
var token = content.Request.Headers["Token"];
if (!string.IsNullOrEmpty(token))
{
//解密用户ticket,并校验用户名密码是否匹配
if (ValidateTicket(token))
{
base.IsAuthorized(actionContext);
}
else
{
HandleUnauthorizedRequest(actionContext);
}
}
//如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
else
{
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 encryptToken)
{
bool flag = false;
try
{
try
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
var json = decoder.Decode(encryptToken, secret, verify: true);
flag = true;
}
catch (TokenExpiredException)
{
Console.WriteLine("Token has expired");
}
catch (SignatureVerificationException)
{
Console.WriteLine("Token has invalid signature");
}
}
catch (Exception ex)
{
}
return flag;
}
}Code language: HTML, XML (xml)
Previous: 统一封装一个Ajax方法