zoukankan      html  css  js  c++  java
  • token

    1、token的作用及使用流程
      token的作用是用于身份验证,即让服务器端知道是谁在进行网络请求,围绕用户身份进行操作。用来操作的token有两个,一个是accesstoken,用来验证身份,另一个是refreshtoken,用来刷新accesstoken。具体流程如下:
      登陆,获取refreshtoken和accesstoken,同时将refreshtoken保存到数据库,refreshtoken有效时长为一天,accesstoken有效时长为两小时,js中创建日期变量,每次accesstoken更新便解析token获取其失效日期用以更新js中日期变量。每次网络请求前获取当前日期并与js中日期变量比较,距离accesstoken失效十分钟内,拦阻当前网络请求并携带refreshtoken获取新的accesstoken。服务器端解析refreshtoken中的身份信息,并由此获取数据库中refreshtoken进行比对,如果成功则更新accesstoken并继续当前网络请求,如果失败则重新登录。js若进行网络请求时accesstoken已过期,则直接重新登录。
    2、JWT-token 介绍
      JWT就是json-web-token的意思,是对token格式的一种设计。该token字符串一共分为三段,第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature)。完整的token字符串就像这样:aaaaa.bbbbb.c1c2c3c4c5
      jwt的头部承载两部分信息:(1)、声明类型,这里是jwt (2)、声明加密的算法 通常直接使用 HMAC SHA256。这两个信息是一个json字符串,会通过base64加密成字符串"aaaaa"
      jwt的载荷承载了你想要传递的token信息及身份信息,这些信息其本质也是一个json字符串,会通过base64加密成字符串"bbbbb"。jwt给出了它建议加上的载荷信息,如下:

    iss (issuer):签发人
    exp (expiration time):过期时间,jwt的过期时间,这个过期时间必须要大于签发时间
    sub (subject):主题
    aud (audience):受众
    nbf (Not Before):生效时间,定义在什么时间之前,该jwt都是不可用的.
    iat (Issued At):签发时间
    jti (JWT ID):编号,jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
    

      除了这些信息,我们还可以加上用户的身份信息,如"UserId"、"UserName"等。上面说了头部信息和载荷信息都是使用base64加密的,是对称加密,其实就是一种基于64个可打印字符来表示二进制数据的方法。加密容易,解密也简单,对计算机而言与明文无异。所以,切记不要放入密码等敏感机密信息。
      jwt的签证信息,这个理解起来就简单了,它会将"aaaaa"和"bbbbb"以及我们设置的私钥(想设置什么私钥都可,123456也行,abcd也行,越难猜越好)这三段字符串连在一起,通过头部信息设置的加密方式(此例实例中我们用的是HMAC SHA256加密方式)来将这段字符串加密成"c1c2c3c4c5"。
      如此我们便生成了jwt完整的token字符串。若是服务器端面对传递而来的token字符串,便会将头部信息、载荷信息和私钥信息重新加密成签证信息,与传递而来的签证信息进行比对,若是对不上便是知道有人动了头部或者载荷信息,爆出异常。

    3、JWT在C#中的使用
      首先在nuget包管理器中,搜索JWT并安装,记得要耐心查看框架版本并选择JWT版本。安装完成之后编写帮助类,代码如下:

    public static class TokenHelper
    {
        public static string SecretKey = "This is a private key for Server";//这个服务端加密秘钥 属于私钥
        private static JavaScriptSerializer myJson = new JavaScriptSerializer();
        public static string GenToken(TokenInfo M)
        {
            var payload = new Dictionary<string, dynamic>
            {
                { "exp", DateTimeOffset.UtcNow.AddSeconds(10).ToUnixTimeSeconds() },//到期时间
                {"UserName", M.UserName},//用于存放当前登录人账户信息
                {"UserSn", M.UserSn}//用于存放当前登录人id信息
            };
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            return encoder.Encode(payload, SecretKey);
        }
    
        public static TokenInfo DecodeToken(string token)
        {
            try
            {
                var json = GetTokenJson(token);
                TokenInfo info = myJson.Deserialize<TokenInfo>(json);
                return info;
            }
            catch (Exception)
            {
    
                throw;
            }
        }
    
        public static string GetTokenJson(string token)
        {
            try
            {
                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 json = decoder.Decode(token, SecretKey, verify: true);
                return json;
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
    
    public class TokenInfo
    {
        public TokenInfo()
        {
            UserName = "andrew";
            UserSn = "123456";
        }
        public string UserName { get; set; }
        public string UserSn { get; set; }
    }
    

      

  • 相关阅读:
    ruby直接底层连接数据库
    debian和ubuntu的sh dash bash
    find locate
    apt-get
    ERROR: The partition with /var/lib/mysql is too full! failed!
    linux访问ftp服务器命令
    win7配置ftp服务器
    黑马程序员_Java基础视频-深入浅出精华版--PPT 文件列表
    黑马程序员_Java基础视频-深入浅出精华版--视频列表
    转:Java项目开发规范参考
  • 原文地址:https://www.cnblogs.com/liangshibo/p/13154119.html
Copyright © 2011-2022 走看看