jwt加密使用于登录


```handlebars
前端登录代码:

	<script src="js/tableserialize.js"></script>
			<script type="text/javascript">

				//获取登录信息
                $("#form1  input[type='submit']").click(function () {
                    var getform1 = $("#form1").serializeObject();
                    alert(JSON.stringify(getform1));
				 
					var url = "http://localhost:59110/api/user/Login";
					$.ajax({

						url: url,
						type: "post",
						data:JSON.stringify(getform1)),
                        dataType: "json",//json写了jq会帮我们转换成数组或者对象 他已经用JSON.parse弄好了
					   contentType: 'application/json;charset=utf-8', //服务器返回json格式数据
                        success: function (data) {
                             
							if (data.Code == 200) {
								alert("成功!" + JSON.stringify(data));
								sessionStorage.setItem("token", data.Data);
							}

						},
						error: function (err) {

							alert("出错了!" + JSON.stringify(err));

						}
					});

				})

				//获取用户信息
				$("#getuserInfo").click(function () {
					var token = sessionStorage.getItem("token");
					alert(token);
					if (token == null || token == "") {
						return true;
					}
					var url = "/api/user/UserInfo";
					$.ajax({
						url: url,
						type: "get",
						headers: {
							token: token
						},
						success: function (data) {
							console.log(JSON.stringify(data));
							if (data != null) {
								alert("请求成功:" + JSON.stringify(data));
							}

						},
						error: function (err) {

							alert("出错了:" + JSON.stringify(err));

						}
					});

				})
			</script>

提供 表单序列化的js:tableserialize.js

; (function ($) {

	jQuery.prototype.serializeObject = function () {
		var obj = new Object();
		$.each(this.serializeArray(), function (index, param) {
			if (!(param.name in obj)) {
				obj[param.name] = param.value;
			}
		});
		return obj;
	};
	 
 })(jQuery);

后台代码:

api部分:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

using WebApiDemoTest.Models;
using myapi.Filters;
using myapi.Models;
using myapi.Models.Auth;
namespace myapi.Controllers
{
    /*
         * 1.通过特性的方式进行JWT验证。
         *  
         * 2.在验证过程中获取jwt的账号信息并存入User.Identity.Name
         * 
         * 3.可以在任意Action 方法中读取User.Identity.Name 属性里的值
         * 
         * 
         * 特性与 过滤器 auth
         * 
         */

    [RoutePrefix(prefix:"api/user")]
    public class userController : ApiController
    {
        [Route(template:"Login")]
        [MyAuth]  //验证操作
        public   IHttpActionResult Login(Login_model login_)
        {

             
            if (ModelState.IsValid)//t通过校验
            {
                return Ok(new ResponseData() {
                    Data = jwtTools.Encoder(new Dictionary<string, object>() 
                    {
                        {"LoginName",login_.userName },
                        {"UserId",12354 },
                         
                    })
                     
                
                });
            }
            else//通过失败
            {
                return Ok(new Models.ResponseData() { Code = 500, Errmessage = "账号或密码有误" });
            }
        }

        /// <summary>
        /// 得到用户信息
        /// </summary>
        /// <returns></returns>
        [MyAuth]
        [HttpGet]
        [Route(template: "UserInfo")]
        public   IHttpActionResult GetUserInfo()
        {
            // 强烈推荐使用ID操作
            //先去数据库获取ID,可以通过ID获取想要的值
            //其他操作
            return Ok(new ResponseData()
            {
                Data = ((UserIdentity)User.Identity).UserId

            }) ;
        }
    }
}

没有引用core,记得引用才得行,

注: // Web API 配置和服务 ,需要配置才可以跨域

config.EnableCors(new EnableCorsAttribute("", "", “*”));

jwt加密部分:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;

using Newtonsoft.Json;
using JWT.Exceptions;
namespace myapi.Models
{
    public class jwtTools
    {
        public static string Key { get; set; } = "Hello  World";
        static  IJwtAlgorithm algorithm = new  HMACSHA256Algorithm();//HMACSHA256加密
        static IJsonSerializer serializer = new JsonNetSerializer();//序列化和反序列
        static IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//Base64编解码
        static IDateTimeProvider provider = new UtcDateTimeProvider();//UTC时间获取

        /// <summary>
        /// jwt加密
        /// </summary>
        /// <param name="payload"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public  static  string  Encoder(Dictionary<string,object> payload, string  key=null)
        {
            if (string.IsNullOrEmpty(key))
            {
                key = Key;
            }
            //添加jwt的一个时效串
            payload.Add("timeout", DateTime.Now.AddDays(1));
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            return encoder.Encode(payload, key);

        }

        /// <summary>
        /// jwt解密
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public   static    Dictionary<string,object >    Decode(string  jwtStr,string key=null)
        {
            if (string.IsNullOrEmpty(key))
            {

                key = Key;
            }

            try
            {
                IJwtValidator validator = new JwtValidator(serializer, provider);//用于验证JWT的类
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);//用于解析JWT的类
             var    json = decoder.Decode(token:jwtStr, key, verify: true);//verify:true表示解析JWT时进行验证,该方法会自动调用validator的Validate()方法,不满足验证会抛出异常,因此我们不用写验证的方法
                 //string 转换为Dictionary  反向转换为对象内容
                var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
                if ((DateTime)result["timeout"] < DateTime.Now)
                    throw new Exception(message: "jwt已经过期,请重新登录");
                result.Remove(key:"timeout");//删除里面的key等于timeout值

                return result;

            }
            catch (TokenExpiredException)//如果当前时间大于负载中的过期时间(负荷中的exp),引发Token过期异常
            {
                throw new Exception(message: "jwt已经过期,请重新登录");
               
            }
            catch (SignatureVerificationException)//如果签名不匹配,引发签名验证异常
            {
                throw new Exception(message: "Token签名不正确!");
                
            }
            catch (Exception)
            {

                throw;
            }

        }
      
    }
}

注:这里是需要引用jwt, 才可进行操作,不然报错

登录验证类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations; 

namespace WebApiDemoTest.Models
{
    public class Login_model
    {   
          
        /// <summary>
        /// 用户名
        /// </summary>
        [Required] //也可以用在界面上
        [EmailAddress]
        [StringLength(maximumLength:100,MinimumLength =5)]
        public string userName { get; set; }
        /// <summary>
        /// 用户密码
        /// </summary>
        [Required]
        [StringLength(maximumLength:30,MinimumLength =6)]
        public string userPwd { get; set; }
    }
}

注:这里需要验证,提高登录安全度

信息响应类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace myapi.Models
{
    public class ResponseData
    {

        public int Code { get; set; } = 200;
        public object Data { get; set; }

        public string  Errmessage { get; set; }
    }
}

验证登录类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

using  myapi.Models;
using System.Net;
using System.Web.Http;
using myapi.Models.Auth;
namespace myapi.Filters
{
    public class MyAuthAttribute : Attribute, IAuthorizationFilter
    {
        
        public bool AllowMultiple => throw new NotImplementedException();

        /// <summary>
        ///  前端响应返回的数据
        /// </summary>
        /// <param name="actionContext">请求返回的内容</param>
        /// <param name="cancellationToken">请求返回的token</param>
        /// <param name="continuation">异步返回的结果</param>
        /// <returns></returns>
        public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            IEnumerable<string> headers;

            //验证jwt
            //如果指定的标头和指定的值存储在 System.Net.Http.Headers.HttpHeaders 集合中,则返回。
            if (actionContext.Request.Headers.TryGetValues(name: "token", out headers))
            {

                var loginName = jwtTools.Decode(jwtStr: headers.First())["LoginName"].ToString();
                var UserId = jwtTools.Decode(jwtStr: headers.First())["UserId"].ToString();

                (actionContext.ControllerContext.Controller as ApiController).User = new  ApplicationUser(loginName, Convert.ToInt32(UserId));
                return  await continuation();

            }
           // 如果不成功返回 ( 等效于 HTTP 状态 401。 System.Net.HttpStatusCode.Unauthorized 指示所请求的资源需要身份验证)
            return new HttpResponseMessage(HttpStatusCode.Unauthorized);
        }
    }
}

注:这里是获取信息时,得到登录时加入header值,获取用户信息。

要获取的接口类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


using System.Security.Principal;
namespace myapi.Models.Auth
{
    public class UserIdentity : IIdentity
    {
        /// <summary>
        /// 构造方法  获取name userId的值
        /// </summary>
        /// <param name="name"></param>
        /// <param name="userId"></param>
        public  UserIdentity(string name,int userId)
        {
            Name = name;
            UserId = userId;
        }
        public string Name { get; }

        public  int UserId { get; }

        public string AuthenticationType { get; }

        public bool IsAuthenticated { get; }
    }

    public class ApplicationUser : IPrincipal
    {

        public   ApplicationUser(string name,int UserId)
        {
            Identity = new UserIdentity(name, UserId);


        }
        public IIdentity Identity { get; }

        public bool IsInRole(string role)
        {
            throw new NotImplementedException();
        }
    }
}

链接起来基本就是一个完整的实体:

有兴趣的可以试试,也可以咨询我。
没加入数据库,可以自己配置下数据库就可以了。

结果演示:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

可以看到值取到了,可以去通过token,取到用户信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你的美,让我痴迷

你的好,我会永远记住你的。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值