Json Web Token(jwt)
一種不錯的身份驗證及授權方案,與 Session 相反,Jwt 將用戶信息存放在 Token 的 payload 字段保存在客戶端,通過 RSA 加密的方式,保證數據不會被篡改,驗證數據有效性。
詳細請參考jwt.io。 我現在還是一枚小白,希望能幫助更多的小白成長。因此文章都是一些比較簡單的使用過程,文字講解較少,怕誤人子弟。
小白成長為大牛過程:知其然而不知其所引然
再知其然而知其所引然
1. 開發環境如下
vs2017+ASP.NET MVC 5+.NET FrameWork4.5.2
2. 在nuget上先添加封裝了jwt使用的框架
因為環境是.NET FrameWork4.5.2 所以我采用3.0.1版本

3.封裝一個JWT幫助類
創建實體類 UserInfo
public string UserName { get; set; }
public string Pwd { get; set; }
public class JwtHelp { //私鑰 web.config中配置 //"GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk"; private static string secret = ConfigurationManager.AppSettings["Secret"].ToString(); /// <summary> /// 生成JwtToken /// </summary> /// <param name="payload">不敏感的用戶數據</param> /// <returns></returns> public static string SetJwtEncode(Dictionary<string, object> payload) { //格式如下 //var payload = new Dictionary<string, object> //{ // { "username","admin" }, // { "pwd", "claim2-value" } //}; 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; } /// <summary> /// 根據jwtToken 獲取實體 /// </summary> /// <param name="token">jwtToken</param> /// <returns></returns> public static UserInfo GetJwtDecode(string token) { 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 userInfo = decoder.DecodeToObject<UserInfo>(token, secret, verify: true);//token為之前生成的字符串 return userInfo; } } }
4.創建JwtController 生成jwtToken看看效果
Get 請求需要改成這樣
return Json(result,JsonRequestBehavior.AllowGet);
public class JwtController : Controller { // GET: Jwt public ActionResult Index() { return View(); } /// <summary> /// 創建jwtToken /// </summary> /// <param name="username"></param> /// <param name="pwd"></param> /// <returns></returns> public ActionResult CreateToken(string username, string pwd) { DataResult result = new DataResult(); //假設用戶名為"admin",密碼為"123" if (username == "admin" && pwd == "123") { var payload = new Dictionary<string, object> { { "username",username }, { "pwd", pwd } }; result.Token = JwtHelp.SetJwtEncode(payload); result.Success = true; result.Message = "成功"; } else { result.Token = ""; result.Success = false; result.Message = "生成token失敗"; } return Json(result);
//get請求需要修改成這樣
//return Json(result,JsonRequestBehavior.AllowGet); } }
5.我喜歡postMan測試神器 你值得擁有

6.AuthorizeAttribute
接下來,我們需要編寫有關權限控制及token解析有關的代碼。
所有操作都在Home里面 將受限Action或Controller打上標簽, 所有訪問都想先權限驗證通過后才能訪問
編寫一個繼承AuthorizeAttribute實現類,根據實體類是否相等。
我先簡單描述下程序執行過程
1.進入驗證入口->驗證核心代碼->
1.返回false進入驗證處理失敗
2.返回true進入訪問的controller/action里面
public class MyAuthorizeAttribute : AuthorizeAttribute { /// <summary> /// 驗證入口 /// </summary> /// <param name="filterContext"></param> public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); } /// <summary> /// 驗證核心代碼 /// </summary> /// <param name="httpContext"></param> /// <returns></returns> protected override bool AuthorizeCore(HttpContextBase httpContext) { //前端請求api時會將token存放在名為"auth"的請求頭中 var authHeader = httpContext.Request.Headers["auth"]; if (authHeader == null) { httpContext.Response.StatusCode = 403; return false; } var userinfo = JwtHelp.GetJwtDecode(authHeader); //舉個例子 生成jwtToken 存入redis中 //這個地方用jwtToken當作key 獲取實體val 然后看看jwtToken根據redis是否一樣 if (userinfo.UserName == "admin" && userinfo.Pwd == "123") return true; httpContext.Response.StatusCode = 403; return false; } /// <summary> /// 驗證失敗處理 /// </summary> /// <param name="filterContext"></param> protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { base.HandleUnauthorizedRequest(filterContext); if (filterContext.HttpContext.Response.StatusCode == 403) { filterContext.Result = new RedirectResult("/Error"); filterContext.HttpContext.Response.Redirect("/Home/Error"); } } }
使用postman 然后再Headers 地方將jswToken 傳入進去

參考資料鏈接
https://www.cnblogs.com/lwhkdash/p/6686999.html
https://www.cnblogs.com/cnki/p/6297182.html
github下載鏈接 上述錯誤,請大家多多包涵。我還是一枚小白。
https://github.com/yaols/JWT.MvcDemo
