赞
踩
简单口述一下这个JWT Token验证和Attribute拦截器在项目中起到的作用
一.Token存在的意义
Token的存是为了实现接口安全,比如当接口地址泄露了,别人随便就能访问了,当我们有了Token,当别人知道了我们的接口地址,他们没有Token,我们后台检测到token为空,就会返回请求错误
二.Attribute拦截器的意义
就是相当于别人调用你的接口方法,我们加了拦截器,别人调用我们接口的时候就会先进入拦截器,我们就可以先在拦截器里面做一个校验什么的操作了,当然拦截器有进入方法前,返回值前,返回值后等的拦截器,前面的文章我有写到过
三.JWT Token验证结合Attribute拦截器在项目中的使用流程简单描述(表达能力略差)
第一步:客户端登录
第二步:验证用户名和密码以及添加Token
第三步:当用户名密码验证通过且Token生成成功,则返回验证成功状态和token值给前端页面
第四步:前端页面接收到返回验证成功状态和token值则把token值存到页面缓存之中(怎么存都行看你们自己)
第五步:当我们进入主页做其它功能请求接口时,先获取页面缓存中的token,携带token请求接口
第六步:当我们请求方法时,方法加了拦截器,就会先进入拦截器,就会判断这个token是否存在且token值正确
第七步:当token传输过来无误就会解析token存储到请求上下文Request上下文中(这个解析之后你们也可以不用一定存储到Request上下文中,根据情况而定)
第八步:然后再进入请求的接口方法体中进行数据操作
下面开始我们Demo实战演习............................................................
1.添加项目
2.添加model
- using System.Collections.Generic;
-
- namespace JwtWebApi.Models
- {
- public class AuthInfo
- {
- //模拟JWT的payload
- public string UserName { get; set; }
-
- public List<string> Roles { get; set; }
-
- public bool IsAdmin { get; set; }
- /// <summary>
- /// 过期时间
- /// </summary>
- public string ExpirationTime { get; set; }
- }
- }

- namespace JwtWebApi.Models
- {
- public class LoginRequest
- {
- public string UserName { get; set; }
-
- public string Password { get; set; }
- }
- }
- namespace JwtWebApi.Models
- {
- public class LoginResult
- {
- public bool Success { get; set; }
-
- public string Token { get; set; }
-
- public string Message { get; set; }
- }
- }
3.添加拦截器(创建一个文件夹Attributes)添加一个ApiAuthorizeAttribute类
- using JWT;
- using JWT.Algorithms;
- using JWT.Serializers;
- using JwtWebApi.Models;
- using System;
- using System.Linq;
- using System.Web.Http;
- using System.Web.Http.Controllers;
-
- namespace JwtWebApi.Attributes
- {
- /// <summary>
- /// 拦截器
- /// </summary>
- public class ApiAuthorizeAttribute: AuthorizeAttribute
- {
- /// <summary>
- /// 验证请求是否携带token
- /// </summary>
- /// <param name="actionContext"></param>
- /// <returns></returns>
- protected override bool IsAuthorized(HttpActionContext actionContext)
- {
- //获取token
- var authHeader = from t in actionContext.Request.Headers
- where t.Key == "auth"
- select t.Value.FirstOrDefault();
-
- //验证token是否为空
- if (authHeader != null)
- {
- string token = authHeader.FirstOrDefault();
- if (!string.IsNullOrEmpty(token))
- {
- try
- {
- const string secret = "To Live is to change the world";
- //secret需要加密
- JWT.IJsonSerializer serializer = new JsonNetSerializer();
- IDateTimeProvider provider = new UtcDateTimeProvider();
- IJwtValidator validator = new JwtValidator(serializer, provider);
- IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
- IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
- IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
-
- var authInfo = decoder.DecodeToObject<AuthInfo>(token, secret, verify: true);
-
- if (authInfo != null)
- {
- //验证token是否超时,这里设置的过期时间为两小时
- if (Convert.ToDateTime(authInfo.ExpirationTime) < DateTime.Now.AddHours(2) && !string.IsNullOrEmpty(authInfo.ExpirationTime))
- {
- actionContext.RequestContext.RouteData.Values.Add("autninfoDate", authInfo);
- return true;
- }
- else return true;
- }
- return false;
- }
- catch (Exception ex)
- {
- return false;
- }
- }
- }
- return false;
- }
- }
- }

4.创建Controller
SignInController 控制器
- using JWT;
- using JWT.Algorithms;
- using JWT.Serializers;
- using JwtWebApi.Models;
- using System;
- using System.Collections.Generic;
- using System.Web.Http;
-
- namespace JwtWebApi.Controllers
- {
- public class SignInController : ApiController
- {
- /// <summary>
- /// 登录/生成token
- /// </summary>
- /// <param name="UserName">用户名</param>
- /// <param name="PassWord">密码</param>
- /// <returns></returns>
- [HttpGet]
- public LoginResult Post(string UserName,string PassWord)
- {
- LoginResult rs = new LoginResult();
- //这是是获取用户名和密码的,这里只是为了模拟
- AuthInfo info = new AuthInfo {
- UserName = UserName, //用户名
- Roles = new List<string> { "Admin", "Manage","YQ" }, //权限
- IsAdmin = true,
- ExpirationTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") };//过期时间
- try
- {
- const string secret = "To Live is to change the world";
- //secret需要加密
- IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
- IJsonSerializer serializer = new JsonNetSerializer();
- IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
- IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
- var token = encoder.Encode(info, secret);
-
- #region 模拟数据库存
- //登录用户名密码验证
- List<LoginRequest> list=new List<LoginRequest>();
- list.Add(new LoginRequest { UserName = "admin", Password = "admin" });
- #endregion
-
- //且数据库有这用户才能登录成功
- if (list.Exists(t => t.UserName == UserName && t.Password == PassWord)==false)
- return new LoginResult { Message = "登录失败,账号或密码错误!", Success = false };
- //验证token是否为空
- if (token==null || token=="")
- return new LoginResult { Message = "登录失败,token生成失败!", Success = false };
-
- return new LoginResult { Message = "登录成功!", Token = token, Success = true };
-
- }
- catch (Exception ex)
- {
- //异常返回
- return new LoginResult { Message = ex.Message, Success = false };
- }
- }
-
- }
- }

UserController 控制器
- using JwtWebApi.Attributes;
- using JwtWebApi.Models;
- using System.Web.Http;
-
- namespace JwtWebApi.Controllers
- {
- public class UserController : ApiController
- {
- /// <summary>
- /// 获取测试token
- /// </summary>
- /// <returns></returns>
- [ApiAuthorize]
- [HttpGet]
- public string Get11()
- {
- AuthInfo info = RequestContext.RouteData.Values["autninfoDate"] as AuthInfo;
- if (info == null)
- {
- return "获取不到,失败";
- }
- else
- {
- return $"获取到了,Auth的Name是 {info.UserName}";
- }
- }
- }
- }

5.更改Home/Index页面内容
index页面内容
- <div class="jumbotron">
- <fieldset>
- <legend>身份验证</legend>
- <form id="form">
- <label for="UserName">用户名:</label><input type="text" name="userName" id="UserName" />
- <br />
- <br />
- <label for="Password">密码:</label><input type="password" name="password" id="PassWord" />
- <br />
- <br />
- </form>
- <button id="login">登录</button>
- </fieldset>
- <br />
-
- <fieldset>
- <button id="invoke">调用接口</button>
- </fieldset>
- <script src="~/Scripts/jquery-3.4.1.js"></script>
- <script src="~/Scripts/jquery-3.4.1.min.js"></script>
- <script>
-
- //调用api站点的登录接口,接口在登录成功后返回一个token。
-
- $("#login").on("click", function () {
- debugger
- var UserName = $("#UserName").val();
- if (!UserName) {
- alert("用户名不能为空!");
- return;
- }
- var PassWord = $("#PassWord").val();
- if (!PassWord) {
- alert("密码不能为空!");
- return;
- }
- $.ajax({
- //url: "https://localhost:44330/api/SignIn/Post?UserName=" + UserName + "&PassWord=" + PassWord + "",
- url: "../../api/SignIn/Post?UserName=" + UserName + "&PassWord=" + PassWord + "",
- method: "get",
- async: false,
- success: function (data) {
- if (data.Success) {
- //为简单起见,将token保存在全局变量中。
- window.token = data.Token;
- alert("登录成功");
- } else {
- alert("登录失败:" + data.Message);
- }
- }, error: function (XMLHttpRequest, textStatus, errorThrown) {
- console.log("请求进入error--" + XMLHttpRequest.status);
- // 状态
- console.log(XMLHttpRequest.readyState);
- // 错误信息
- console.log(textStatus);
- console.log(XMLHttpRequest.responseText);
- }
- });
- });
-
- //调用api站点的获取数据的接口,该接口要求身份验证。
- $("#invoke").on("click", function () {
- console.log(window.token);
- $.ajax({
- //url: "https://localhost:44330/api/User/Get11",
- url: "../../api/User/Get11",
- method: "get",
- headers: {
- "auth": window.token
- }, //通过请求头来发送token,放弃了通过cookie的发送方式
- complete: function (jqXHR, textStatus) {
- alert(jqXHR.responseText);
- }, error: function (XMLHttpRequest, textStatus, errorThrown) {
- console.log("请求进入error--" + XMLHttpRequest.status);
- // 状态
- console.log(XMLHttpRequest.readyState);
- // 错误信息
- console.log(textStatus);
- console.log(XMLHttpRequest.responseText);
- }
- });
- });
- </script>
- </div>

完结撒花........
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。