WebAPI通过JWT加密完成登录状态验证

WebAPI通过JWT加密完成登录状态验证

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

namespace Demo04.Models
{
    //用户类
    public class User
    {
        [EmailAddress]
        [Required]
        public string Email { get; set; }
        [Required]
        public string Password { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Demo04.Models
{
    //此类用于规范返回消息
    public class Msg
    {
        public int Code { get; set; } = 200;
        public object Data { get; set; }
        public string ErrorMsg { get; set; }
    }
}
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Demo04
{
    //此类用于Jwt的加密与解密
    public class JwtTool
    {
        //jwt密钥
        public static string KEY { get; set; } = "MSGasdjaojOIJOIJJJasdopoPOO";
        //加密方法
        public static string EnCode(Dictionary<string, object> payload, string key = null)
        {
            if (string.IsNullOrEmpty(key))
            {
                key = KEY;
            }
            //加密过程
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            payload.Add("timeout", DateTime.Now.AddDays(1));//添加新键值对用于jwt时间验证
            return encoder.Encode(payload, key);//返回加密结果字符串
        }
        //解密方法
        public static Dictionary<string, object> DeCode(string jwtstr, string key = null)
        {
            if (string.IsNullOrEmpty(key))
            {
                key = KEY;
            }
            //解密过程
            IJsonSerializer serializer = new JsonNetSerializer();
            IDateTimeProvider provider = new UtcDateTimeProvider();
            IJwtValidator validator = new JwtValidator(serializer, provider);
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            var algorithm = new HMACSHA256Algorithm();
            IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
            var json = decoder.Decode(jwtstr, key, verify: true);
            //反序列成Dictionary<>类型
            var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
            //验证时间
            if ((DateTime)result["timeout"]<DateTime.Now)
            {
                throw new Exception("JWT过期");
            }
            result.Remove("timeout");//移除时间键值对
            return result;
        }
    }
}
using Demo04.Models.Identity;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace Demo04.Controllers
{
    //此类为自定义的过滤器,继承于Attribute,实现IAuthorizationFilter(授权过滤器)接口
    internal class MyValidAttribute : Attribute, IAuthorizationFilter
    {
        public bool AllowMultiple => throw new NotImplementedException();
        public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            if (actionContext.Request.Headers.TryGetValues("token", out var header))
            {	
                //获得token并存入header
                var email = JwtTool.DeCode(header.First())["Email"].ToString();//获得Email键的值
                (actionContext.ControllerContext.Controller as ApiController).User = new ApplicationUser(new AuthIdentity(email));//将值存入User.Identity.Name
                return await continuation();
            }
            return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);//返回未经授权的对应Code
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;

namespace Demo04.Models.Identity
{
    //若要使用User.Identity,须先实现IPrincipal与IIdentity接口
    public class AuthIdentity : IIdentity
    {
        public AuthIdentity(string name)
        {
            Name = name;
        }
        public string Name { get; }
        public string AuthenticationType => throw new NotImplementedException();
        public bool IsAuthenticated => throw new NotImplementedException();
    }

    public class ApplicationUser : IPrincipal
    {
        public ApplicationUser(IIdentity identity)
        {
            Identity = identity;
        }
        public IIdentity Identity { get; }
        public bool IsInRole(string role)
        {
            throw new NotImplementedException();
        }
    }
}
using Demo04.Models;
using Demo04.Models.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace Demo04.Controllers
{
    [RoutePrefix("api/user")]
    public class UserController : ApiController
    {
        [HttpPost]
        [Route("login")]
        public IHttpActionResult Login(User model)
        {
            if (ModelState.IsValid)//传入参数须先通过过滤器验证
            {
                //将加密后的登录信息返回给调用者
                return Ok(new Msg()
                {
                    //JWT加密
                    Data = JwtTool.EnCode(new Dictionary<string, object>()
                    {
                        {"Email",model.Email }
                    })
                });
            }
            return Ok(new Msg()
            {
                Code=500,
                ErrorMsg = "参数验证失败"
            }) ;
        }
        [HttpGet]
        [MyValid]//调用此方法须在header的token中放入登陆时返回的JWT加密字符串
        [Route("info")]
        //返回email
        public IHttpActionResult GetUserInfo()
        {
            return Ok(new Msg()
            {
                Data = ((User.Identity) as AuthIdentity).Name
            });
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值