AuthenticationHelper验证帮助类
现在,我们已经可以编写验证类了,利用刚刚已创建的缓存帮助类和JWT帮助类。
AuthenticationHelper验证帮助类代码如下:
public class AuthenticationHelper { /// <summary> /// 默认30分钟 /// </summary> /// <param name="username"></param> public static void AddUserAuth(string username) { var token = JwtHelper.SetJwtEncode(username, 30); CacheHelper.SetCache(username, token, new TimeSpan(TimeSpan.TicksPerHour / 2)); } public static void AddUserAuth(string username, TimeSpan ts) { var token = JwtHelper.SetJwtEncode(username, ts.Minutes); CacheHelper.SetCache(username, token, ts); } public static string GetToken(string username) { var cachetoken = CacheHelper.GetCache(username); return cachetoken.ParseToString(); } public static bool CheckAuth(string token) { var dicInfo = JwtHelper.GetJwtDecode(token); var username = dicInfo["username"]; var cachetoken = CacheHelper.GetCache(username.ToString()); if (!cachetoken.IsNullOrEmpty() && cachetoken.ToString() == token) { return true; } else { return false; } } }
如代码所示,我们实现了验证token创建、验证token获取、验证Token校验三个方法。
到此,我们的基础代码已经编写完了,下面进入验证的应用。
Fliter
首先,在Global.asax文件中,为我们WebApi添加一个过滤器,代码如下:
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); //webapiFilter System.Web.Http.GlobalConfiguration.Configuration.Filters.Add(new HttpPermissionFilter()); System.Web.Http.GlobalConfiguration.Configuration.Filters.Add(new HttpExceptionFilter()); //mvcFliter System.Web.Mvc.GlobalFilters.Filters.Add(new MvcExceptionFilter()); System.Web.Mvc.GlobalFilters.Filters.Add(new MvcPermissionFilter()); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } }
代码中创建了四个过滤器,分别是MVC的请求和异常过滤器和WebApi的请求和异常过滤器。
这里我们主要看WebApi的请求过滤器——HttpPermissionFilter。代码如下:
public class HttpPermissionFilter : System.Web.Http.Filters.ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { string url ="请求Url" + actionContext.Request.RequestUri.ToString(); var action = actionContext.ActionDescriptor.ActionName.ToLower(); var controller = actionContext.ControllerContext.ControllerDescriptor.ControllerName.ToLower(); if (controller != "login" && controller != "loginout") { //客户端段token获取 var token = actionContext.Request.Headers.Authorization != null ? actionContext.Request.Headers.Authorization.ToString() : ""; //服务端获取token 与客户端token进行比较 if (!token.IsNullOrEmpty() && AuthenticationHelper.CheckAuth(token)) { //认证通过,可进行日志等处理 } else { throw new Exception("Token无效"); } } } }
我们的HttpPermissionFilter类继承了System.Web.Http.Filters.ActionFilterAttribute,这样他就可以截获所有的WebApi请求了。
然后我们重写了他的OnActionExecuting方法,在方法里,我们查询到当前请求的Controller的名称,然后对其进行了一个简单的判断,如果是login(登录)或loginout(登出),那我们就不对他的token进行验证。如果是其他请求,则会从请求的Headers的Authorization属性里读取token,并使用AuthenticationHelper类对这个token进行正确性的验证。
WebApi接口
现在我们编写WebApi接口,编写一个登录接口和一个普通请求接口。
登录接口:这里我们使用AuthenticationHelper类创建一个token,并把他存储到缓存中。
然后再把token返回给调用者。
普通接口:这里我们不做任何操作,就是简单的返回成功,因为是否可以访问这个接口,已经又Filter控制了。
代码如下:
public class LoginController : ApiController { public string Get(string username,string pwd) { AuthenticationHelper.AddUserAuth(username, new TimeSpan(TimeSpan.TicksPerMinute * 5));//5分钟 string token = AuthenticationHelper.GetToken(username); return token; } } public class RequestController : ApiController { public string Get() { return "请求成功"; } }
测试页面
现在我们编写测试页面,这里我们实现三个按钮,登录、带token访问Api、无token访问Api。
代码如下:
<div> <script> $(document).ready(function () { $("#request").click(function () { var token = window.localStorage.getItem('token'); if (token) { $.ajax({ type: "GET", url: "http://localhost:50525/api/Request", success: function (data) { $('#con').append('<div> success:' + data + '</div>'); console.log(data); }, beforeSend: function (xhr) { //向Header头中添加Authirization xhr.setRequestHeader("Authorization", token); }, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#con').append('<div> error:' + errorThrown + '</div>'); } }); } else { alert("token不存在"); } }); $("#requestNotoken").click(function () { var token = window.localStorage.getItem('token'); if (token) { $.ajax({ type: "GET", url: "http://localhost:50525/api/Request", success: function (data) { $('#con').append('<div> success:' + data + '</div>'); console.log(data); }, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#con').append('<div> error:' + errorThrown + '</div>'); } }); } else { alert("token不存在"); } }); $("#login").click(function () { $.ajax({ type: "GET", url: "http://localhost:50525/api/Login/?username=kiba&pwd=518", success: function (data) { $('#con').append('<div> token:' + data + '</div>'); console.log(data); window.localStorage.setItem('token', data) } }); }); }); </script> <h1>测试JWT</h1> <button id="login">登录</button> <button id="request">带token访问Api</button> <button id="requestNotoken">无token访问Api</button> <div id="con"></div> </div>
测试结果如下:
如上图所示,我们已经成功实现简单的token验证。
到此JWT的实战应用就已经介绍完了。
本文作者:kiba518,全栈.Net软件工程师
声明:本文为 脚本之家专栏作者 投稿,未经允许请勿转载。