发表于: 2019-11-15 23:40:51

1 969


今天完成的事:
1、学习cookie,并进行添加、删除,实现自动登录。
cookie是保存在本地终端的数据,由服务器生成,发送给浏览器,浏览器把cookie以键值对的形式保存在某个目录的文本文件中,下次请求同一网站就会将该cookie发送给服务器。每个域的cookie数量是有限制的,为了确保不会被恶意使用,且减少磁盘空间的占用。
之前就编写了登录注册页面,在登录时,添加cookie,用以自动登录。
添加cookie后,浏览器F12,显示cookie。且关闭浏览器也不会删除。

点击自动登录,获取请求中的cookie,遍历查询用户名,而后根据用户名查询对应的密码,与cookie中的密码对比,一致则自动登录。
 

点击注销,则删除cookie。



需要注意的是,修改、删除cookie时,除了value和maxAge之外的属性要完全一致,否则浏览器会视为不同cookie,不予覆盖,导致修改、删除失败。
登录时添加cookie:

自动登录:
// 自动登录
@RequestMapping("/autoLogin")
public ModelAndView autoLogin(ModelAndView mav,HttpServletRequest request){
    System.out.println("进入了自动登录的Controller!");
    // 获取cookie
    Cookie[] cookies = request.getCookies();
    // 数组为空判断
    if (null==cookies || cookies.length==0) {
        mav.addObject("msg", "没有用户信息,无法自动登录!");
    }else {
        // 遍历cookie,找用户名
        for (Cookie cookie : cookies) {
            // 如果有名为name的cookie,获取其用户名
            if (cookie.getName().equals("name") && cookie.getValue() != null) {
                String cookieUsername = cookie.getValue();
                // 遍历cookie,找用户密码
                for (Cookie cookie2 : cookies) {
                    // 如果有名为password的cookie,获取其用户密码
                    if (cookie2.getName().equals("password") && cookie2.getValue() != null) {
                        String cookiePassword = cookie2.getValue();
                        try {
                            // 根据用户名查找数据库中密码
                            String realPassword = userService.getPasswordByName(cookieUsername);
                            // 对比cookie中密码与数据库存储密码
                            if (cookiePassword.equals(realPassword)) {
                                logger.info("登录用户:"+ cookieUsername +",密码:"+ cookiePassword);
                                mav.addObject("msg", "自动登录成功!");
                            } else {
                                mav.addObject("msg", "自动登录失败,密码有误!");
                            }
                        } catch (NullPointerException e) {
                            mav.addObject("msg", "自动登录失败,其他原因!");
                        }
                    }
                }
            }
        }
    }
    mav.setViewName("login");
    return mav;
}
注销、删除cookie:
将value设为空字符串,setAge设为0,即为销毁cookie。

2、进行DES加密。
加密分为可逆加密、不可逆加密。
可逆加密:加密后可以解密,进行对比。如DES。
不可逆加密:加密后不能解密,只能以相同方式加密,而后对比。如MD5。
可逆加密还分为对称加密和非对称加密。
对称加密:加密解密的密钥一样,DES就是对称加密。
非对称加密:加密解密的密钥不一样,加密为公钥,解密为私钥。
使用DES加密需导入如下jar包。根据方法的不一样吧,应该有不需要导包的。

其中生成密钥的方式有很多类,这里选择了KeyGenerator类。
生成密钥,进行加密、解密。
// 生成一个DES密钥
public static String getKey(){
    try {
        // 获取指定算法(DES)的密钥
        KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
        // 初始化密钥,指定密钥大小,可自定义随机源,但需注意密钥长度必须是8的倍数
        keyGenerator.init(56);
        // 生成一个Key
        SecretKey generateKey = keyGenerator.generateKey();
        // 转变为字节数组
        byte[] encoded = generateKey.getEncoded();
        // 生成密钥字符串
        String encodeHexString = Hex.encodeHexString(encoded);
        return encodeHexString;
    } catch (Exception e) {
        e.printStackTrace();
        return "密钥生成错误.";
    }
}
// 加密
public static String encryptor(String str,String Key){
    String s=null;
    try {
        DESKeySpec desKey = new DESKeySpec(Key.getBytes());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKey);
        // 指定加密的算法
        Cipher cipher = Cipher.getInstance("DES");
        // 初始化密码器,用密钥 secretKey 进入加密模式,ENCRYPT_MODE
        cipher.init(Cipher.ENCRYPT_MODE,securekey);
        // 获得加密后的字节数组
        byte[] bytes=cipher.doFinal(str.getBytes());
        s= Base64.encodeBase64String(bytes);
    } catch (Exception e) {
        e.printStackTrace();
        return "加密错误.";
    }
    return s;
}
// 解密,步骤与加密一致,区别在于初始化的模式设置
public static String decryptor(String buff,String Key){
    String s=null;
    try {
        DESKeySpec desKey = new DESKeySpec(Key.getBytes());
        // 指定解密的算法
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKey);
        Cipher cipher = Cipher.getInstance("DES");
        // 初始化密码器,用密钥 secretKey 进入解密模式,DECRYPT_MODE
        cipher.init(Cipher.DECRYPT_MODE,securekey);
        // 先将密文转为数组,再获得解密后的字节数组
        byte[] responseByte=cipher.doFinal(Base64.decodeBase64(buff));
        s=new String(responseByte);
    } catch (Exception e) {
        e.printStackTrace();
        return "解密错误.";
    }
    return s;
}
这里需要注意的是加密解密的步骤是一样的,只是在初始化密码器时,设置的加密解密模式不同,而进行相应的操作。

测试类如下,相同明文多次加密,得到的密文都不同。

3、MD5加密。
MD5加密有很多特点,其中就是不可逆性,当然暴力破解不算。
并且其具有压缩性,任意长度的数据,算出的MD5值都是一样的长度。
一致性,相同明文生成的密文是一样的,这点是方便了前后对比,但是感觉有点不安全。。
主要用途就是文件校验,查看文件在传输中有没有被篡改,密码加密,因为无法反向解析,所以用来进行私密信息的传递。
java中通过MessageDigest类进行MD5的算法,如下。

且MD5可以进行加盐,也就是掺杂一些自定义的字符串。这里将加密后的密文转为了16进制的32位字符串,说是16进制数据的方便存储。。


并且MD5的加密还可以通过导包的工具类直接进行数据的加密。如下方法是导下图的包,因为不同包的方法有很多。。
这里是toUpperCase()方法可以将加密后生成的小写字母转为大写字母。


明天计划的事:
1、学习session、token、jwt。
2、设置拦截器进行页面访问的拦截。
遇到的问题:
1、问题主要是加密的方法太多了,网上的信息太杂,不知道哪个好,要用哪个,最后才没有管太多,随便找了个照着写了就。。
收获:
1、学习cookie,并进行添加、删除,实现自动登录。
2、进行DES加密、MD5加密。

返回列表 返回列表
评论

    分享到