zoukankan      html  css  js  c++  java
  • Vue、Vuex+Cookie 实现自动登陆 。

    概述

      1、自动登陆实现思路。

      2、vuex + cookie 多标签页状态保持。

    自动登陆的需求:

      1、登陆时勾选自动登陆,退出登陆登陆到期后再次登陆后自动填写表单(记住密码)或访问登陆页自动登陆。

      2、安全性需求,cookie 的有效性判断应该放到服务端。

    实现细节

      1、后台:一个静态的登陆管理类 负责管理登陆用户,这里设计了两个 cookie 一个用来保存登陆信息、一个用来保存自动登陆信息。

    登陆cookie 的有效时间是 30 分钟,自动登陆cookie 的有效时间是 3 天,分别保存了用户名、编码、密码;用户名、编码、密码、时间戳。

    后台包含,RSA加密算法、cookie 管理、登陆相关业务(登入、登出、过滤器)。不干兴趣跳过,看前端代码。

      1     /// <summary>
      2     /// 登录用户管理
      3     /// </summary>
      4     public static class LoginUserManager
      5     {
      6         public const string DBENLOGININ = "DBEN.OP.LOGININ";
      7         public const string DBENAUTOLOGIN = "DBEN.OP.AUTOLOGIN";
      8         public const string DBENUSERCODE = "DBEN.OP.USERCODE";
      9         public const string DBENUSERNAME = "DBEN.OP.USERNAME";
     10         public const string DBENUSERPWD = "DBEN.OP.USERPASSWORD";
     11 
     12         /// <summary>
     13         /// RSA 加解密实例
     14         /// </summary>
     15         public static RSAApply RSAApply
     16         {
     17             get
     18             {
     19                 return new RSAApply(
     20          ConfigHelper.GetAppSetting("DBEN.StaticRSAPublicKey", @"MIGfM
     21 A0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBRxFQos7Nc77goLB6cz2SM6Ae7OuuOTkycG2eyP
     22 Lds7+hE8s6bqJMfdY6EOlPjGraATXSCsrPnowWeq2p59xyejJLlCfX3dE+Br5FuUG+MwK7K6i
     23 HQ2lJLZlvnnmDqjmHO2+k14VOFwlXNOKkciWVsjT/mr4Xj4olG2gjOhWvqQIDAQAB"),
     24          ConfigHelper.GetAppSetting("DBEN.StaticRSAPrivateKey", @"MIIC
     25 dwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMFHEVCizs1zvuCgsHpzPZIzoB7s6
     26 645OTJwbZ7I8t2zv6ETyzpuokx91joQ6U+MatoBNdIKys+ejBZ6rann3HJ6MkuUJ9fd0T4Gvk
     27 W5Qb4zArsrqIdDaUktmW+eeYOqOYc7b6TXhU4XCVc04qRyJZWyNP+avhePiiUbaCM6Fa+pAgM
     28 BAAECgYAePxDmnZPfcw2b+YmkoAQyrQGR1WHMkgfxbMa64pefOlHy0zYqnsWnUsoDrEHWwRK3
     29 qxjRFf9HHnity+UBgddtjRrSW9ly+5zSvTTVb3wHfSqV/xJsakZ3M8MjVLCQXZarXTbRlYBnx
     30 eFLcvvfouDHbefK6cqIpEk1uWllq7eNQQJBAOpWf2gsvGnFTU0vrx77Ed1QHH0C4ldss63N91
     31 /YbrmNl9jQNcWD2DG3tw3ToSM8JIAb1Rdw9/kwpoqW9qp0mI8CQQDTJOWQum/+oovU7MZrgzR
     32 K3N/wVXt4GIDgL4k48NSvzA+jRGf5MdphsqQKHuws9F4O+P7w/mK2QOHx4ys8OqBHAkEAnj6L
     33 Cu4qzcJO0TDCMUmaZrkSg9jOv/rH2zabNj4Rh3v2bpMrvJWsCObm1o9y4Thb7abd31aKHdycm
     34 joXmEPkQQJAW62hn/3TsxSQ8pr8bKJDil3tPkVfnv3Et5LsWjT3pH1OLO3+10y2LcWLRHm4wq
     35 w4SvgCelF6OvhhIs4ob7Zk8QJBAIXEwsLcy9xZaRt85dIWuJFfbuAmCXiNWSJEhIFYPkLUvi2
     36 QHZTdLHpSbi5oCPIVKw4CDTAP4b+JfGrrFaZjWNc="));
     37             }
     38         }
     39 
     40         /// <summary>
     41         /// 已登录
     42         /// </summary>
     43         /// <param name="userCode"></param>
     44         public static void SetLoginIn(string userCode, string userName, string userPassword)
     45         {
     46             var dic = new Dictionary<string, string>
     47             {
     48                 { DBENUSERCODE, userCode },
     49                 { DBENUSERNAME, userName },
     50                 { DBENUSERPWD, userPassword }
     51             };
     52             CookieManager.SetCookie(DBENLOGININ, RSAApply.GetCiphertext(dic, false));
     53         }
     54 
     55         public static void SetLoginOut()
     56         {
     57             CookieManager.RemoveCookie(DBENLOGININ);
     58         }
     59 
     60         /// <summary>
     61         /// 自动登录
     62         /// </summary>
     63         /// <param name="userCode"></param>
     64         public static void SetAutoLogin(string userCode, string userName, string userPassword)
     65         {
     66             if (CookieManager.GetCookie(DBENAUTOLOGIN) == null)
     67             {
     68                 //首次勾选自动登录,创建自动登录的cookie。
     69                 var dic = new Dictionary<string, string>
     70                 {
     71                     { DBENUSERCODE, userCode },
     72                     { DBENUSERNAME, userName },
     73                     { DBENUSERPWD, userPassword }
     74                 };
     75                 CookieManager.SetCookie(new HttpCookie(DBENAUTOLOGIN, RSAApply.GetCiphertext(dic, true)) { Expires = DateTime.Now.AddDays(RSAApply.ValidityDays) });
     76             }
     77             //通过自动登录也要设置已登录的 cookie
     78             SetLoginIn(userCode, userName, userPassword);
     79         }
     80 
     81         /// <summary>
     82         /// 检查客户端状态
     83         /// </summary>
     84         /// <returns></returns>
     85         public static bool CheckClientStatus(out Dictionary<string, string> user)
     86         {
     87             /****
     88              * 如果存在 已登录 cookie 且译文有效,用户未被禁用,则返回true
     89              * 否则检验 自动登录 cookie。
     90              * 自动登录 cookie 存在且译文有效,自动登录后返回 true。
     91              * */
     92 
     93             var cookie = CookieManager.GetCookie(DBENLOGININ);
     94             if (cookie != null)
     95             {
     96                 return CheckCiphertext(cookie.Value, out user);
     97             }
     98             else
     99             {
    100                 // 如果不是已登录,检查是否存在自动登录 cookie
    101                 cookie = CookieManager.GetCookie(DBENAUTOLOGIN);
    102                 if (cookie != null)
    103                 {
    104                     if (CheckCiphertext(cookie.Value, out user))
    105                     {
    106                         //将此用户设置为已登录
    107                         SetLoginIn(user[DBENUSERCODE], user[DBENUSERNAME], user[DBENUSERPWD]);
    108                         return true;
    109                     }
    110                 }
    111                 user = null;
    112                 return false;
    113             }
    114         }
    115 
    116         /// <summary>
    117         /// 获取客户端用户信息
    118         /// </summary>
    119         /// <returns>返回一个从 cookie 创建的新实例</returns>
    120         public static OPUserEntity GetClientUserInfo()
    121         {
    122             OPUserEntity res = null;
    123             if (CheckClientStatus(out Dictionary<string, string> user))
    124             {
    125                 res = new OPUserEntity
    126                 {
    127                     Code = user[DBENUSERCODE],
    128                     UserName = user[DBENUSERNAME],
    129                     Password = user[DBENUSERPWD]
    130                 };
    131             }
    132             return res;
    133         }
    134 
    135         /// <summary>
    136         /// 校验密文有效性,包括密文能否解密、账户有效性。
    137         /// </summary>
    138         /// <param name="ciphertext">密文</param>
    139         /// <param name="user">如果返回值为方式则返回一个空实例</param>
    140         /// <returns></returns>
    141         private static bool CheckCiphertext(string ciphertext, out Dictionary<string, string> user)
    142         {
    143             user = new Dictionary<string, string>();
    144             var repo = RF.ResolveInstance<OPUserEntityRepository>();
    145             if (RSAApply.TryGetSource(ciphertext, ref user))
    146             {
    147                 if (user.TryGetValue(DBENUSERCODE, out string userCode))
    148                 {
    149                     if (user.TryGetValue(DBENUSERPWD, out string userPwd))
    150                     {
    151                         if (user.TryGetValue(DBENUSERNAME, out string userName))
    152                         {
    153                             var count = repo.CountBy(new CommonQueryCriteria
    154                             {
    155                                 { OPUserEntity.UserNameProperty,userName },
    156                                 { OPUserEntity.CodeProperty,userCode },
    157                                 { OPUserEntity.PasswordProperty,userPwd },
    158                                 { OPUserEntity.EnabledProperty,true },
    159                             });
    160                             return count > 0;
    161                         }
    162                     }
    163                 }
    164             }
    165 
    166             return false;
    167         }
    168 
    169 
    170     }
    LoginUserManager
    • 组合类 RSA 加密实例
     1     /// <summary>
     2     /// RSA 加密应用实例
     3     /// </summary>
     4     public class RSAApply
     5     {
     6         readonly string xmlPublicKey;
     7         readonly string xmlPrivateKey;
     8         readonly RSACryption rSACryption;
     9         const string TIMESTAMPKEY = "RSAApply_timeStamp";
    10 
    11         /// <summary>
    12         /// 追加时间戳情况下的有效天数 
    13         /// </summary>
    14         public int ValidityDays { get; internal set; }
    15 
    16         public RSAApply(string base64PublicKey, string base64PrivateKey)
    17         {
    18             this.xmlPublicKey = RSAKeyConvert.RSAPublicKeyBase64ToXml(base64PublicKey);
    19             this.xmlPrivateKey = RSAKeyConvert.RSAPrivateKeyBase64ToXml(base64PrivateKey);
    20             rSACryption = new RSACryption();
    21         }
    22 
    23         /// <summary>
    24         /// 获取密文
    25         /// </summary>
    26         /// <returns></returns>
    27         public string GetCiphertext(Dictionary<string, string> source, bool timestamp = false)
    28         {
    29             if (timestamp)
    30             {
    31                 source.Add(TIMESTAMPKEY, TimeHelper.GetTStamp());
    32             }
    33             var sourceStr = JsonConvert.SerializeObject(source, Formatting.Indented);
    34             var ciphertext = rSACryption.RSAEncrypt(xmlPublicKey, sourceStr);
    35             return ciphertext;
    36         }
    37 
    38         /// <summary>
    39         /// 获取明文
    40         /// </summary>
    41         /// <returns></returns>
    42         public bool TryGetSource(string cipertext, ref Dictionary<string, string> source)
    43         {
    44             var sourceStr = rSACryption.RSADecrypt(xmlPrivateKey, cipertext);
    45             source = JsonConvert.DeserializeObject<Dictionary<string, string>>(sourceStr);
    46 
    47             if (source.TryGetValue(TIMESTAMPKEY, out string timeStemp))
    48             {
    49                 if ((DateTime.Now - long.Parse(timeStemp).ToTimeStamp()).TotalDays > ValidityDays)
    50                 {
    51                     return false;
    52                 }
    53                 source.Remove(TIMESTAMPKEY);
    54             }
    55             return true;
    56         }
    57     }
    RSAApply
    •  RSA 加密帮助类
      1 public class RSACryption
      2     {
      3 
      4         #region 私有属性
      5 
      6         private Encoding rsaEncoding
      7         {
      8             get
      9             {
     10                 return Encoding.Unicode;
     11             }
     12         }
     13 
     14         private Encoding hashEncoding
     15         {
     16             get
     17             {
     18                 return Encoding.UTF8;
     19             }
     20         }
     21 
     22         #endregion
     23 
     24         #region RSA 加密解密
     25 
     26         #region RSA 的密钥产生
     27 
     28         /// <summary>  
     29         /// RSA产生密钥  
     30         /// </summary>  
     31         /// <param name="xmlPrivateKey">私钥</param>  
     32         /// <param name="xmlPublicKey">公钥</param>
     33         /// <returns></returns>
     34         public bool RSACreateKey(out string xmlPrivateKey, out string xmlPublicKey)
     35         {
     36             try
     37             {
     38                 var rsaProvider = new RSACryptoServiceProvider(1024);
     39                 xmlPrivateKey = rsaProvider.ToXmlString(true);
     40                 xmlPublicKey = rsaProvider.ToXmlString(false);
     41                 return true;
     42             }
     43             catch (Exception)
     44             {
     45                 xmlPrivateKey = string.Empty;
     46                 xmlPublicKey = string.Empty;
     47                 return false;
     48             }
     49         }
     50 
     51         #endregion
     52 
     53         #region RSA加密函数
     54 
     55         /// <summary>
     56         /// RSA 加密
     57         ///   首先对原始字符串做MD5哈希,然后再对哈希值加密。
     58         /// </summary>
     59         /// <param name="publicKeyBase64String"></param>
     60         /// <param name="source"></param>
     61         /// <returns></returns>
     62         public string RSAEncryption(string publicKeyBase64String, string source)
     63         {
     64             string hashValue = string.Empty;
     65             this.ComputeMD5Hash(source, ref hashValue);
     66             var pck = RSAKeyConvert.RSAPublicKeyBase64ToXml(publicKeyBase64String);
     67             var ciphertext = this.RSAEncrypt(pck, hashValue);
     68             return ciphertext;
     69         }
     70 
     71         /// <summary>  
     72         /// RSA的加密函数  
     73         /// </summary>  
     74         /// <param name="xmlPublicKey">公钥</param>
     75         /// <param name="srouce">待加密文本</param>
     76         /// <returns></returns>
     77         public string RSAEncrypt(string xmlPublicKey, string srouce)
     78         {
     79             byte[] plainTextBytes = this.rsaEncoding.GetBytes(srouce);
     80             return this.RSAEncrypt(xmlPublicKey, plainTextBytes);
     81         }
     82 
     83         /// <summary>  
     84         /// RSA的加密函数   
     85         /// </summary>  
     86         /// <param name="xmlPublicKey">公钥</param>  
     87         /// <param name="sourceBytes">加密后的字节数组</param>  
     88         /// <returns></returns>  
     89         public string RSAEncrypt(string xmlPublicKey, byte[] sourceBytes)
     90         {
     91             try
     92             {
     93                 byte[] cypherTextBytes;
     94                 string res = string.Empty;
     95                 var rsaProvider = new RSACryptoServiceProvider();
     96                 rsaProvider.FromXmlString(xmlPublicKey);
     97                 cypherTextBytes = rsaProvider.Encrypt(sourceBytes, false);
     98                 res = Convert.ToBase64String(cypherTextBytes);
     99                 return res;
    100             }
    101             catch (Exception) { return string.Empty; }
    102         }
    103 
    104         #endregion
    105 
    106         #region RSA的解密函数
    107 
    108         /// <summary>  
    109         /// RSA 解密
    110         ///   解密失败则返回空字符串
    111         /// </summary>  
    112         /// <param name="xmlPrivateKey">XML格式的私钥</param>  
    113         /// <param name="encryptString">加密后的字符串</param>  
    114         /// <returns>解密后的字符串</returns>  
    115         public string RSADecrypt(string xmlPrivateKey, string encryptString)
    116         {
    117             byte[] encryptBytes = Convert.FromBase64String(encryptString);
    118             return this.RSADecrypt(xmlPrivateKey, encryptBytes);
    119         }
    120 
    121         /// <summary>  
    122         /// RSA 解密
    123         ///   解密失败则返回空字符串
    124         /// </summary>  
    125         /// <param name="xmlPrivateKey">XML格式的私钥</param>  
    126         /// <param name="encryptBytes">加密后的字节数组</param>  
    127         /// <returns>解密后的字符串</returns>
    128         public string RSADecrypt(string xmlPrivateKey, byte[] encryptBytes)
    129         {
    130             try
    131             {
    132                 var rsaProvider = new RSACryptoServiceProvider();
    133                 rsaProvider.FromXmlString(xmlPrivateKey);
    134                 byte[] dypherTextBytes = rsaProvider.Decrypt(encryptBytes, false);
    135                 string res = this.rsaEncoding.GetString(dypherTextBytes);
    136                 return res;
    137             }
    138             catch (Exception) { return string.Empty; }
    139         }
    140 
    141         #endregion
    142 
    143         #endregion
    144 
    145         #region RSA数字签名
    146 
    147         #region MD5 Hash
    148 
    149         /// <summary>  
    150         /// 计算Hash(MD5)
    151         /// </summary>  
    152         /// <param name="sourceString">原始字符串</param>  
    153         /// <param name="hashString">Hash值</param>  
    154         /// <returns>是否成功</returns>  
    155         public bool ComputeMD5Hash(string sourceString, ref string hashString)
    156         {
    157             byte[] hashBytes = new byte[0];
    158             var res = this.ComputeMD5Hash(sourceString, ref hashBytes);
    159             hashString = Convert.ToBase64String(hashBytes);
    160             return res;
    161         }
    162 
    163         /// <summary>  
    164         /// 计算Hash(MD5)
    165         /// </summary>  
    166         /// <param name="srourceString">原始字符串</param>  
    167         /// <param name="hashBytes">Hash值</param>  
    168         /// <returns>是否成功</returns>  
    169         public bool ComputeMD5Hash(string srourceString, ref byte[] hashBytes)
    170         {
    171             try
    172             {
    173                 var md5Provider = HashAlgorithm.Create("MD5");
    174                 byte[] buffer = this.hashEncoding.GetBytes(srourceString);
    175                 hashBytes = md5Provider.ComputeHash(buffer);
    176                 return true;
    177             }
    178             catch (Exception) { return false; }
    179         }
    180 
    181         #endregion
    182 
    183         #region RSA 创建签名
    184 
    185         /// <summary>  
    186         /// 生成RSA签名
    187         ///   签名算法:MD5
    188         /// </summary>  
    189         /// <param name="xmlPrivateKey">XML私钥</param>  
    190         /// <param name="hashString">待签名Hash值</param>  
    191         /// <param name="signatureString">签名的值</param>  
    192         /// <returns>是否成功</returns>  
    193         public bool CreateSignature(string xmlPrivateKey, string hashString, ref string signatureString)
    194         {
    195             byte[] hashBytes = Convert.FromBase64String(hashString);
    196             var signatureBytes = new byte[0];
    197             var res = this.CreateSignature(xmlPrivateKey, hashBytes, ref signatureBytes);
    198             signatureString = Convert.ToBase64String(signatureBytes);
    199             return res;
    200         }
    201 
    202         /// <summary>  
    203         /// 生成RSA签名
    204         ///   签名算法:MD5
    205         /// </summary>  
    206         /// <param name="xmlPrivateKey">XML私钥</param>  
    207         /// <param name="hashBytes">待签名Hash值</param>  
    208         /// <param name="signatureString">签名的值</param>  
    209         /// <returns>是否成功</returns>  
    210         public bool CreateSignature(string xmlPrivateKey, byte[] hashBytes, ref string signatureString)
    211         {
    212             var signatureBytes = new byte[0];
    213             var res = this.CreateSignature(xmlPrivateKey, hashBytes, ref signatureBytes);
    214             signatureString = Convert.ToBase64String(signatureBytes);
    215             return res;
    216         }
    217 
    218         /// <summary>  
    219         /// 生成RSA签名
    220         ///   签名算法:MD5
    221         /// </summary>  
    222         /// <param name="xmlPrivateKey">XML私钥</param>  
    223         /// <param name="hashString">待签名Hash值</param>  
    224         /// <param name="signatureBytes">签名的值</param>
    225         /// <returns>是否成功</returns>  
    226         public bool CreateSignature(string xmlPrivateKey, string hashString, ref byte[] signatureBytes)
    227         {
    228             byte[] hashBytes = Convert.FromBase64String(hashString);
    229             return this.CreateSignature(xmlPrivateKey, hashBytes, ref signatureBytes);
    230         }
    231 
    232         /// <summary>  
    233         /// 生成RSA签名
    234         ///   签名算法:MD5
    235         /// </summary>
    236         /// <param name="xmlPrivateKey">XML私钥</param>  
    237         /// <param name="hashBytes">待验证的Hash值</param>  
    238         /// <param name="signatureBytes">签名的值</param>  
    239         /// <returns>是否成功</returns>  
    240         public bool CreateSignature(string xmlPrivateKey, byte[] hashBytes, ref byte[] signatureBytes)
    241         {
    242             try
    243             {
    244                 var rsaProvider = new RSACryptoServiceProvider();
    245 
    246                 rsaProvider.FromXmlString(xmlPrivateKey);
    247                 var rsaFormatter = new RSAPKCS1SignatureFormatter(rsaProvider);
    248                 //设置算法
    249                 rsaFormatter.SetHashAlgorithm("MD5");
    250                 //执行签名   
    251                 signatureBytes = rsaFormatter.CreateSignature(hashBytes);
    252                 return true;
    253             }
    254             catch (Exception) { return false; }
    255         }
    256 
    257         #endregion
    258 
    259         #region RSA 验证签名
    260 
    261         /// <summary>  
    262         /// 验证RSA签名  
    263         /// </summary>  
    264         /// <param name="xmlPublicKey">XML公钥</param>  
    265         /// <param name="hashString">待验证的Hash值</param>  
    266         /// <param name="signatureString">签名的值</param>  
    267         /// <returns></returns>  
    268         public bool VerifySignature(string xmlPublicKey, string hashString, string signatureString)
    269         {
    270             byte[] signatureBytes = Convert.FromBase64String(signatureString);
    271             byte[] hashBytes = Convert.FromBase64String(hashString);
    272             return this.VerifySignature(xmlPublicKey, hashBytes, signatureBytes);
    273         }
    274 
    275         /// <summary>  
    276         /// 验证RSA签名  
    277         /// </summary>  
    278         /// <param name="xmlPublicKey">XML公钥</param>  
    279         /// <param name="hashBytes">待验证的Hash值</param>  
    280         /// <param name="signatureString">签名的值</param>  
    281         /// <returns></returns>  
    282         public bool VerifySignature(string xmlPublicKey, byte[] hashBytes, string signatureString)
    283         {
    284             byte[] signatureBytes = Convert.FromBase64String(signatureString);
    285             return this.VerifySignature(xmlPublicKey, hashBytes, signatureBytes);
    286         }
    287 
    288         /// <summary>  
    289         /// 验证RSA签名  
    290         /// </summary>  
    291         /// <param name="xmlPublicKey">XML公钥</param>  
    292         /// <param name="hashString">待验证的Hash值</param>  
    293         /// <param name="signatureBytes">签名的值</param>  
    294         /// <returns>验签结果</returns>  
    295         public bool VerifySignature(string xmlPublicKey, string hashString, byte[] signatureBytes)
    296         {
    297             byte[] hashBytes = Convert.FromBase64String(hashString);
    298             return this.VerifySignature(xmlPublicKey, hashBytes, signatureBytes);
    299         }
    300 
    301         /// <summary>  
    302         /// 验证RSA签名
    303         /// </summary>  
    304         /// <param name="xmlPublicKey">XML公钥</param>  
    305         /// <param name="hashBytes">待验证的Hash值</param>  
    306         /// <param name="signatureBytes">签名的值</param>  
    307         /// <returns>验签结果</returns>  
    308         public bool VerifySignature(string xmlPublicKey, byte[] hashBytes, byte[] signatureBytes)
    309         {
    310             try
    311             {
    312                 var rsaProvider = new RSACryptoServiceProvider();
    313                 rsaProvider.FromXmlString(xmlPublicKey);
    314                 var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsaProvider);
    315                 //指定解密的时候HASH算法为MD5   
    316                 rsaDeformatter.SetHashAlgorithm("MD5");
    317                 if (rsaDeformatter.VerifySignature(hashBytes, signatureBytes))
    318                 {
    319                     return true;
    320                 }
    321                 else
    322                 {
    323                     return false;
    324                 }
    325             }
    326             catch (Exception) { return false; }
    327         }
    328 
    329         #endregion
    330 
    331         #endregion
    332 
    333     }
    RSACryption
    •  RSA 密钥格式转换类
     1     /// <summary>
     2     /// RSA密钥格式转换
     3     /// </summary>
     4     public class RSAKeyConvert
     5     {
     6 
     7         #region 私钥转换
     8 
     9         /// <summary>    
    10         /// RSA私钥 Base64 To XML
    11         /// </summary>    
    12         /// <param name="privateKey">Base64格式的私钥</param>    
    13         /// <returns></returns>   
    14         public static string RSAPrivateKeyBase64ToXml(string privateKey)
    15         {
    16             var privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
    17             return
    18                 string.Format(
    19                     "<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
    20                     Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
    21                     Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
    22                     Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
    23                     Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
    24                     Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
    25                     Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
    26                     Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
    27                     Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
    28         }
    29 
    30         /// <summary>    
    31         /// RSA私钥 XML To Base64
    32         /// </summary>    
    33         /// <param name="privateKey">XML格式的私钥</param>    
    34         /// <returns></returns>   
    35         public static string RSAPrivateKeyXmlToBase64(string privateKey)
    36         {
    37             XmlDocument doc = new XmlDocument();
    38             doc.LoadXml(privateKey);
    39             BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
    40             BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
    41             BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
    42             BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
    43             BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
    44             BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
    45             BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
    46             BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));
    47             RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);
    48             PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
    49             byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
    50             return Convert.ToBase64String(serializedPrivateBytes);
    51         }
    52 
    53         #endregion
    54 
    55         #region 公钥转换
    56 
    57         /// <summary>    
    58         /// RSA公钥 Base64 To XML
    59         /// </summary>    
    60         /// <param name="publicKey">Base64格式的公钥</param>    
    61         /// <returns></returns>    
    62         public static string RSAPublicKeyBase64ToXml(string publicKey)
    63         {
    64             RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
    65             return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
    66                 Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
    67                 Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
    68         }
    69 
    70         /// <summary>    
    71         /// RSA公钥 XML To Base64
    72         /// </summary>    
    73         /// <param name="publicKey">XML格式的公钥</param>    
    74         /// <returns></returns>   
    75         public static string RSAPublicKeyXmlToBase64(string publicKey)
    76         {
    77             XmlDocument doc = new XmlDocument();
    78             doc.LoadXml(publicKey);
    79             BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
    80             BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
    81             RsaKeyParameters pub = new RsaKeyParameters(false, m, p);
    82             SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
    83             byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
    84             return Convert.ToBase64String(serializedPublicBytes);
    85         }
    86 
    87         #endregion
    88 
    89     }
    RSAKeyConvert
    •  mvc 过滤器
     1 public class APIAuthedAttribute : ActionFilterAttribute
     2     {
     3         public override void OnActionExecuting(HttpActionContext context)
     4         {
     5             base.OnActionExecuting(context);
     6             if (!LoginUserManager.CheckClientStatus(out Dictionary<string, string> user))
     7             {
     8                 context.Response = context.Request.CreateResponse<Result>(
     9                     HttpStatusCode.OK,
    10                     new  
    11                     {
    12                         StatusCode = 1000,
    13                         Message = "请先登录",
    14                         Success = false
    15                     });
    16             }
    17         }
    18     }
    APIAuthedAttribute

         2、前台 

    •   添加 vuex 目录结构。

    •   安装 vuex 、js-cookie
    npm install --save vuex js-cookie 
     1 // initial state
     2 // shape: [{ id, quantity }]
     3 import {AuthUser} from "../../api/api";
     4 import * as Cookies from "js-cookie"
     5 
     6 const state = {
     7     loginState: {
     8         loginIn: false,
     9         user: {
    10             userName: ""
    11         }
    12     }
    13 }
    14 
    15 // getters
    16 const getters = {
    17     userName: (state, getters, rootState) => {
    18         if (state.loginState.loginIn) {
    19             return state.loginState.user.userName
    20         }
    21     },
    22     offLine: (state, getters, rootState) => {
    23         return !state.loginState.loginIn;
    24     }
    25 }
    26 
    27 //actions
    28 const actions = {
    29     //从服务器端校验本地登录 Cookie 有效性
    30     authUser({state, commit}) {
    31         return  AuthUser().then(res => {
    32             debugger;
    33             if (res.Success) {
    34                 commit('loginIn', {userName: res.Data.UserName});
    35                 return true;
    36             } else {
    37                 commit('loginOut');
    38                 return false;
    39             }
    40         });
    41     }
    42 }
    43 
    44 
    45 // mutations
    46 const mutations = {
    47     //登入状态
    48     loginIn(state, user) {
    49         state.loginState.loginIn = true;
    50         state.loginState.user = user;
    51         debugger;
    52         Cookies.set('loginState', state.loginState, {expires: 1});
    53     },
    54     //登出状态
    55     loginOut(state) {
    56         state.loginState.loginIn = false;
    57         state.loginState.user = {};
    58         Cookies.remove('loginState');
    59     },
    60     syncLoginState(state) {
    61         debugger;
    62         let cookieState = Cookies.getJSON('loginState');
    63         if (cookieState) {
    64             state.loginState = cookieState;
    65         }
    66     }
    67 }
    68 
    69 export default {
    70     namespaced: true,
    71     state,
    72     getters,
    73     actions,
    74     mutations
    75 }
    user.js
     1 import Vue from 'vue'
     2 import Vuex from 'vuex'
     3 import user from './modules/user'
     4 
     5 Vue.use(Vuex)
     6 
     7 const debug = process.env.NODE_ENV !== 'production'
     8 
     9 export default new Vuex.Store({
    10     modules: {
    11         user
    12     },
    13     strict: debug,
    14     plugins:  []
    15 })
    index.js
    • 在入口函数添加用户登陆状态判断 比如main.js
    router.beforeEach((to, from, next) => {
        debugger;
        //离线用户跳转到首页
        if (to.path != '/') {
            router.app.$store.commit('user/syncLoginState');
            if (router.app.$store.getters['user/offLine']) {
    
                //离线用户鉴权,如果成功会自动登录
                router.app.$store.dispatch('user/authUser').then((res) => {
                    if (res) {
                        next();
                    }else {
                        next({path: '/'});
                    }
                });
                return;
            }
        }
        next();
    });

    就这些了,登入,登出等操作就不贴代码了。

    总结一下用到的点:

      1、vuex 的存储源是一个自己定义的 state 对象,也就是说是脚本中一个 实例,它的作用域是当前页面,如果再开一个浏览器标签页是取不到的。同理 localstorage 、 sessionStorage 也是一样的。

      2、vuex actions 可以执行异步方法,可以返回 promise 。比如 请求api,执行 setTimeout ,使用  dispatch 调用,上面有例子。

      3、用新标签页请求一个路由时,代码执行顺序 router( vue 路由守护) => app .created( vue 根实例的  life hook ) => com(路由组件)。所以讲用户状态判断放到路由守卫里。

    来源:

    https://www.npmjs.com/package/js-cookie   

    https://vuex.vuejs.org/zh/guide/actions.html

  • 相关阅读:
    微信、陌陌等著名IM软件设计架构详解
    腾讯首度公开S级手游品质管理方法
    input(file)按钮美化
    巧用css提高浏览器兼容性
    开博首记
    接口测试
    列表、元组操作
    Cacti应用
    Cacti修改采集精度为1分钟
    Centos Cacti 0.8.8g
  • 原文地址:https://www.cnblogs.com/zhuwansu/p/9341494.html
Copyright © 2011-2022 走看看