JWT API 跨域验证实战 仅供参考

上一篇文章说到JWT API 跨域验证实战,这一篇从完整login 打,跨域访问带有权限的页面。

资源

SiteA

SiteB

Summery

jS:

        SiteA js postMessageToken to siteB,siteB get the Token, and send request by adding header and the Token, then redirect the page need to verify

Server:

        MVC框架

        Model

                UserInfo // 保存用户信息,和验证内容

public class UserInfo
    {
        /// <summary>
        /// name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Email
        /// </summary>
        public string Email { get; set; }
        /// <summary>
        /// PassWord
        /// </summary>
        public string PassWord { get; set; }
        /// <summary>
        /// role
        /// </summary>
        public List<string> Roles { get; set; }

        /// <summary>
        /// is admin
        /// </summary>
        public bool IsAdmin { get; set; }

        /// <summary>
        /// expiry date
        /// </summary>
        public DateTime? ExpiryDateTime { get; set; }
    }

                JwtResult

                JWT加密,解密过程

                Token的创建

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Newtonsoft.Json;

namespace MVCWeb.Models
{
    public class JwtResult {
        public string JwtCode { get; set; }
        public string StatusCode { get; set; }
        public string Message { get; set; }
    }
    public class JwtHelper
    {
        private string m_Secret = "THC";
        public string EncodeJwt(UserInfo userInfo)
        {
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            return encoder.Encode(userInfo, m_Secret);
        }

        public UserInfo DecodeJwt(string token)
        {
            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 userInfo = decoder.DecodeToObject<UserInfo>(token, m_Secret, verify: true);//token为之前生成的字符串
            return userInfo;
        }
        public JwtResult CreateToken(string UserName, string PassWord)
        {
            if (string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(PassWord))
                throw new Exception("参数为空");

            JwtResult jwtResult;
            try
            {
                //var param = HttpContext.Request["UserName"];  
                //param = HttpContext.Request["PassWord"];
                if (!UserName.Equals("test") || !PassWord.Equals("test"))
                {
                    throw new Exception("用户密码不正确。");
                }

                UserInfo pUserLoginInfo = new UserInfo() { Name = UserName, PassWord = PassWord };
                JwtHelper pHelper = new JwtHelper();
                string sJwt = pHelper.EncodeJwt(pUserLoginInfo);
                jwtResult = new JwtResult()
                {
                    JwtCode = sJwt,
                    StatusCode = "200",
                    Message = "success"
                };
                return jwtResult;
            }
            catch (Exception ex)
            {
                jwtResult = new JwtResult()
                {
                    JwtCode = "",
                    StatusCode = "403",
                    Message = ex.Message
                };
            }

            return jwtResult;
        }
    }
}

Filter:      

  AppAuthorizeAttribute,自动验证过程,本代码支持两证验证,一是登录验证,二是头部auto验证,任何一种满足都可以拥有访问权限,需要注意点,无论哪种验证,等待验证额通过后,我都会把Token对象保存在Session中,//System.Web.HttpContext.Current.Session["tokenInfo"] = jr,目的是访问有权限的页面时候,便于通过验证

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCWeb.Models;

namespace MVCWeb.Filters
{
    public class AppAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// 验证入口
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
        }


        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            JwtHelper pHelper = new JwtHelper();
            try
            {
                JwtResult jr = (JwtResult)GHelper.GetCurrentTokenInfo();
                //前端请求api时会将token存放在名为"auth"的请求头中
                var authHeader = httpContext.Request.Headers["auth"];
                /*
                if (authHeader == null)
                {
                    httpContext.Response.StatusCode = 403;
                    return false;
                }
                */

                if (authHeader != null)
                {
                    jr = new JwtResult();
                    jr.JwtCode = authHeader;
                }
                else if (jr != null)
                {
                }
                else {
                    httpContext.Response.StatusCode = 403;
                    return false;
                }


                var userinfo = pHelper.DecodeJwt(jr.JwtCode);
                if (userinfo != null)
                {

                    jr.Message = "success";
                    jr.StatusCode = "200";
                    System.Web.HttpContext.Current.Session["tokenInfo"] = jr;
                    return true;
                }

                httpContext.Response.StatusCode = 403;
                return false;
            }
            catch
            {
                httpContext.Response.StatusCode = 403;
                return false;
            }
        }

        /// <summary>
        /// 验证失败处理
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            System.Web.HttpContext.Current.Session.Clear();
            base.HandleUnauthorizedRequest(filterContext);
            if (filterContext.HttpContext.Response.StatusCode == 403)
            {
                //filterContext.Result = new RedirectResult("/Error");
                filterContext.HttpContext.Response.Redirect("/account/login");
            }
        }
    }
}

        Controls:

AccountController

登录后保存token到sesssion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCWeb.Models;

namespace MVCWeb.Controllers
{
    public class AccountController : Controller
    {
        // GET: Account
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]   //返回页面,展示登录页面
        public ActionResult Login()
        {
            return View();
        }


        [HttpPost]    //提交登录,开始登录时执行业务逻辑
        public ActionResult Login(UserInfo user)
        {
            /*
            if (ModelState.IsValid)     //触发实体验证,如果返回true,则通过验证登录成功
            {
                if (user.Name == "test" && user.PassWord == "test")
                {
                    return base.Redirect("/Home/Index");
                }
                else {
                    return Content("用户名或密码有误!");
                }
            }
            return base.Redirect("Home/Index");
            */
            if (ModelState.IsValid)
            {
                JwtHelper jh = new JwtHelper();
                JwtResult jr = jh.CreateToken(user.Name, user.PassWord);
                System.Web.HttpContext.Current.Session["tokenInfo"] = jr;
                if (jr.Message == "success")
                {
                    //return RedirectToAction("index", "Home", jr);   //url后有参数
                    return base.Redirect("/Home/Index");
                }
                else
                {
                    return Content("用户名或密码有误!");
                }
            }
            return Content("fail to login!");
        }
    }
}

HomeController

将被访问带有权限的页面  [AppAuthorize],首先需要通过验证,才能访问

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCWeb.Filters;
using MVCWeb.Models;

namespace MVCWeb.Controllers
{
    [AppAuthorize]
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            //to do....
            JwtResult jr = (JwtResult)GHelper.GetCurrentTokenInfo();
            //解析token  =>  jr
            //...

            UserInfo pUser = new UserInfo()
            {
                Name = "Test",
                PassWord = "Test"
            };
            //ViewBag.Token = jr.JwtCode;
            //ViewBag.Message = jr.Message;
            //ViewBag.Status = jr.StatusCode;
            
            return View(pUser);
        }
        public string test() {
            return "test";
        }
    }
}

       THCController

未经过授权的页面,目的是仅供跨域者使用,是一个空页面,或者中转页面

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCWeb.Filters;
using MVCWeb.Models;

namespace MVCWeb.Controllers
{
    //[AppAuthorize]
    public class THCController : Controller
    {
        // GET: THC
        public ActionResult Index()
        {
            return View();
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值