发表于: 2020-07-02 21:00:33

1 1729


今天完成的事:

Cookie 技术产生源于 HTTP 协议在互联网上的急速发展。随着互联网时代的策马奔腾,带宽等限制不存在了,人们需要更复杂的互联网交互活动,就必须同服务器保持活动状态(简称:保活)。于是,在浏览器发展初期,为了适应用户的需求技术上推出了各种保持 Web 浏览状态的手段,其中就包括了 Cookie 技术。Cookie 在计算机中是个存储在浏览器目录中的文本文件,当浏览器运行时,存储在 RAM 中发挥作用 (此种 Cookies 称作 Session Cookies),一旦用户从该网站或服务器退出,Cookie 可存储在用户本地的硬盘上 (此种 Cookies 称作 Persistent Cookies)。

Cookie时效性:目前有些 Cookie 是临时的,有些则是持续的。临时的 Cookie 只在浏览器上保存一段规定的时间,一旦超过规定的时间,该 Cookie 就会被系统清除。

Cookie使用限制:Cookie 必须在 HTML 文件的内容输出之前设置;不同的浏览器 (Netscape Navigator、Internet Explorer) 对 Cookie 的处理不一致,使用时一定要考虑;客户端用户如果设置禁止 Cookie,则 Cookie 不能建立。 并且在客户端,一个浏览器能创建的 Cookie 数量最多为 300 个,并且每个不能超过 4KB,每个 Web 站点能设置的 Cookie 总数不能超过 20 个。

执行流程:

A:首先,客户端会发送一个http请求到服务器端。

B: 服务器端接受客户端请求后,发送一个http响应到客户端,这个响应头,其中就包含Set-Cookie头部。

C:在客户端发起的第二次请求(注意:如果服务器需要我们带上Cookie,我们就需要在B步骤上面拿到这个Cookie然后作为请求头一起发起第二次请求),提供给了服务器端可以用来唯一标识客户端身份的信息。这时,服务器端也就可以判断客户端是否启用了cookies。尽管,用户可能在和应用程序交互的过程中突然禁用cookies的使用,但是,这个情况基本是不太可能发生的,所以可以不加以考虑,这在实践中也被证明是对的。

为了方便理解,可以先看下这张流程执行图加深概念




Session :

Session是对于服务端来说的,客户端是没有Session一说的。Session是服务器在和客户端建立连接时添加客户端连接标志,最终会在服务器软件(Apache、Tomcat、JBoss)转化为一个临时Cookie发送给给客户端,当客户端第一请求时服务器会检查是否携带了这个Session(临时Cookie),如果没有则会添加Session,如果有就拿出这个Session来做相关操作。


Token :

token是用户身份的验证方式,我们通常叫它:令牌。最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。还可以把不变的参数也放进token,避免多次查库。


应用场景:

A:当用户首次登录成功(注册也是一种可以适用的场景)之后, 服务器端就会生成一个 token 值,这个值,会在服务器保存token值(保存在数据库中),再将这个token值返回给客户端.

B:客户端拿到 token 值之后,进行本地保存。(SP存储是大家能够比较支持和易于理解操作的存储)

C:当客户端再次发送网络请求(一般不是登录请求)的时候,就会将这个 token 值附带到参数中发送给服务器.

D:服务器接收到客户端的请求之后,会取出token值与保存在本地(数据库)中的token值做对比

对比一:如果两个 token 值相同, 说明用户登录成功过!当前用户处于登录状态!

对比二:如果没有这个 token 值, 则说明没有登录成功.

对比三:如果 token 值不同: 说明原来的登录信息已经失效,让用户重新登录.


编写Controller,设置登录,注册,注销功能

使用DES对用户ID和登录时间加密,生成Token,放入Cookie中,拦截器里通过Cookie中判断Token的有效性来判断用户是否登录。


加密分为对称加密和非对称加密

对称加密:

优点:算法公开、计算量小、加密速度快、加密效率高、可逆

缺点:双方使用相同钥匙,安全性得不到保证

现状:对称加密的速度比公钥加密快很多,在很多场合都需要对称加密,

算法: 在对称加密算法中常用的算法有:DES3DES、TDEA、Blowfish、RC2、RC4、RC5IDEA、SKIPJACK、AES等。不同算法的实现机制不同,可参考对应算法的详细资料

相较于DES和3DES算法而言,AES算法有着更高的速度和资源使用效率,安全级别也较之更高了,被称为下一代加密标准

非对称加密:

非对称密码体制的特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快,不可逆

对称密码体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。所以保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样传输对方的密钥了

我们用到的MD5就是非对称加密,DES为对称加密,它们都是工具类


public class UserController {

@Resource
   private UserService userService;

   private static Logger logger = Logger.getLogger(UserController.class);

   //首页
   @RequestMapping("/main")
public String main() {
return "main";
   }

//跳转到登陆页面
   @RequestMapping("/tologin")
public String toLogin() throws Exception {
return "login";
   }

//登录验证
   @RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(@RequestParam(value = "name", required = false) String name,
                       @RequestParam(value = "password", required = false) String password, Model model,
                       HttpServletResponse httpServletResponse,HttpSession session) throws Exception {


logger.info("输入的名字========" + name);

       //判断数据库中是否有该用户名
       if (userService.logincheck(name) != null) {
//查询用户
           User user = userService.logincheck(name);
           user.setName(name);
           //获取用户密码
           String psw = user.getPassword();
           logger.debug(psw + "=====");

           System.out.println(name + "====接收名字=======");
           logger.info(password + "==========接收密码====");
           //获取用户盐值
           String salt = user.getSalt();
           logger.info(salt + "==========数据库盐值========");
           //对盐值和密码加密
           String saltpassword = salt + password;
           String md5Digest = MD5Util.GetMD5Code(saltpassword);

           //设置密码
           user.setPassword(md5Digest);
           logger.info(md5Digest + "========加密加盐的密码=====");

           //判断用户密码与加密后的密码是否一样
           if (psw.equals(md5Digest)) {
model.addAttribute("name", name);

               //根据用户名获取id
               Integer id = user.getId();
               //使用系统当前时间和id生成唯一token,格式为键值对
               String token = id + "=" + System.currentTimeMillis();
               //使用DES加密
               String tokenDES = DESUtil.getEncryptString(token);
               System.out.println("加密后的token" + tokenDES);
               //保存到cookies
               Cookie cookie = new Cookie("token", tokenDES);
               //设置cookie过期时间 单位为秒
               cookie.setMaxAge(7000);

               System.out.println("========cookie==========");
               //返回cookie
               httpServletResponse.addCookie(cookie);

               System.out.println(cookie);
               System.out.println("==============");
               model.addAttribute("user", name);

               logger.info("=======登录成功======");
               //重定向进入学员表
               return "redirect:/user/allBmb";

           } else {
model.addAttribute("error", "账号或密码错误");
               logger.info("=======账号密码错误======");
               return "login";
           }
} else {
//如果输入空值或未登录就访问则提示该消息
           model.addAttribute("error", "请先登录");

           return "login";
       }
}


//转向注册页面
   @RequestMapping("/toregister")
public String toregister() {
return "register";
   }

//注册
   @RequestMapping("/register")
public String register(@RequestParam("name") String name,
                          @RequestParam("password") String password) {
//获取指定长度的盐值
       String salt = StringUtil.getRandomString(10);
       String saltpassword = salt + password;

       //创建对象
       User user = new User();
       //设置名字
       user.setName(name);
       //设置盐值
       user.setSalt(salt);
       //MD5加密加盐
       String md5Digest = MD5Util.GetMD5Code(saltpassword);
       //设置密码
       user.setPassword(md5Digest);

       userService.register(user);
       //登录
       return "login";
   }

@RequestMapping("logout")
public String logout(HttpServletResponse httpServletResponse,
                        HttpServletRequest httpServletRequest) {
//获取cookies
       Cookie[] cookies = httpServletRequest.getCookies();

       if (cookies != null) {
//System.out.println("开始遍历");
           //System.out.println(cookies);
           // 遍历
           for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
System.out.println(cookie);
                   //设置时间为0
                   cookie.setMaxAge(0);
                   System.out.println(cookie);
                   //重置cookie
                   httpServletResponse.addCookie(cookie);
                   //回到首页
                   return "myView1";
               }
}
}return "myView1";



效果展示,首页


登录页面






点击注销


访问学员页,回到登录页面


注册用户

查看数据库


明天计划的事:部署到服务器,做深度思考

遇到的困难:我日志不知道为啥打不出来。。。

收获:











返回列表 返回列表
评论

    分享到