发表于: 2020-01-04 14:05:23

2 1036


啥也不说就是干!!!

今天完成的事情:

1、添加登录页面

<body>
<div class="header">
   <div class="am-g">
       <h1>后台信息系统</h1>

       <p></p>
   </div>
   <hr/>
</div>
<div class="am-g">
   <div class="am-u-lg-6 am-u-md-8 am-u-sm-centered">
       <h3>欢迎登录</h3>
       <hr>
       <div class="am-form" id="login">
           <fieldset>
               <label>账号:</label>

               <!--  <input type="text" minlength="11" required/> -->
               <input type="text" id="mobile" name="mobile" minlength="11" value=""/>
               <br>
               <label for="password">密码:</label>
               <input type="password" id="password"/>
               <input type="hidden" id="passwords" name="password"/>
               <br>
           </fieldset>
           <div class="am-cf">
               <button class="am-btn am-btn-secondary" id="sub" type="button" onClick="login()">登录</button>
           </div>
       </div>

       <hr>
       <p>© 2018 HuiHui</p>
   </div>
</div>
</body>

页面展示效果如下:

其中 onClick 方法是调用 ajax 定义的方法(Ajax 属于前端部分,这里只是简单地了解一下)

function login() {
$("#passwords").val(($("#password").val()));
       if ($("#mobile").val() == '') {
           myAlert("用户名不能为空");
           return;
       }
       if ($("#passwords").val() == '') {
          myAlert("密码不能为空");
           return;
       }
       $.ajax({
          url: '${pageContext.request.contextPath}/admin/login',
           type: 'post',
           async: false,
           timeout: 5000,          // 设置超时时间
           data: {mobile: $("#mobile").val(), password: $("#passwords").val()},
           success: function (data) {
//                data = eval("(" + data + ")");
               if (data.code == '0') {
                   window.location.href = "${pageContext.request.contextPath}/student/list";
               } else {
                   myAlert(data.message);
               }

      }

})

}

先对输入框里面的值进行前端校验,比如用户名,密码格式。如果正确则发起请求

这里可以看到 url 表示接口地址,type 是提交的方法,success:funcation(data),是接口回调

其中 data 表示接口返回值。根据接口返回值进一步处理,如果成功就请求学生信息列表

@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public ResultInfo<Student> doLogin(String mobile, String password, Map<String, Object> map, HttpServletResponse response) throws Exception {
   ResultInfo<Student> resultInfo = new ResultInfo<Student>();
   if (mobile.equals("zhou") && MD5Utils.MD5(password).equals(MD5Utils.MD5("123"))) {
       Student student = studentService.queryStudentInfoById(10);
       if (student != null) {
           map.put("student", student);
           Date timeDate = new Date();
           map.put("time", timeDate);
           resultInfo.setMessage("登录成功");
           resultInfo.setCode(ResultInfo.OK);
       }

   } else {
       resultInfo.setMessage("用户名或密码错误");
       resultInfo.setCode(ResultInfo.ERROR);
   }
   return resultInfo;

}

/student/list 请求的方法

@RequestMapping("/list")
public String list(@RequestParam(required = false,defaultValue = "1") Integer pageNum,@RequestParam(required = false,defaultValue = "10") Integer pageSize,HashMap<String,Object> map){
PageInfo<Student> ps = studentService.getStudentList(pageNum,pageSize);
   map.put("stuInfos",ps.getList());
   return "list";
}

启动项目,输入 http://localhost:8080/login.jsp,然后输入用户名密码,验证通过重定向到学生信息列表页

这里对于传递的密码要进行 MD5 加盐加密

/**
* 获取MD5字符串
*/
public static String getMD5(String content) {
try {
       MessageDigest digest = MessageDigest.getInstance("MD5");
       digest.update(content.getBytes());
       return getHashString(digest);
   } catch (NoSuchAlgorithmException e) {
       e.printStackTrace();
   }
   return null;
}

private static final String SALT = "0fdfa5e5a88bebae640a5d88e7c84708";

/**
* 获取加盐的MD5字符串
*/
public static String getMD5WithSalt(String content) {
   return getMD5(getMD5(content) + SALT);
}

private static String getHashString(MessageDigest digest) {
   StringBuilder builder = new StringBuilder();
   for (byte b : digest.digest()) {
       builder.append(Integer.toHexString((b >> 4) & 0xf));
       builder.append(Integer.toHexString(b & 0xf));
   }
   return builder.toString();
}

以上是简单的登录流程操作,那么对于一些页面或者接口怎么才能控制登录的权限,或者说要验证登录通过以后才能访问呢,这就需要 SpringMVC 拦截器对相应的请求进行拦截,然后做统一的登录验证。为了方便统一配置,要在需要验证登录的路径加 /u 前缀。

例如:/u/sutdent/list

那么对于登录校验来说,一般会在登录之后一般会将 sessionId 相关的信息保存到 cookies 中通过服务器返回给前端,下次请求前端需要将这些 cookies 信息携带,服务器接收 cookies 信息后对 session 进行校验,合法就通过,不合法就拒绝

2、Session、Cookies、Token

1) Session

session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相等)表明他就是张三。

session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。

2) Cookies

cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。

cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。

  • cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中
  • 现在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用
  • 用session只需要在客户端保存一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的。
  • 如果只用cookie不用session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大

3) Token

在Web领域基于Token的身份验证随处可见。在大多数使用Web API的互联网公司中,tokens 是多用户下处理认证的最佳方式。

以下几点特性会让你在程序中使用基于Token的身份验证

a. 无状态、可扩展

b. 支持移动设备

c. 跨程序调用

d. 安全


3、在登录操作中增加 Token

一般 token 返回给客户端然后,前端持久化到 Cookie 

或者存储在本地(web前端存储在 localstorage 移动前端持久化到配置文件或数据库里,每次请求可以携带在 http header 字段里面)

在服务器一般存于数据库中


修改上面的登录逻辑,使用 DES 对 用户ID 和登录时间加密,生成 Token,放入 Cookie 中

今天就学到这里,下午请半天假

明天计划的事情:

1、学习SpringMVC 拦截器,并对请求做统一登录校验

2、Java 常见的加密算法学习

遇到的问题:

暂无

收获:

学习了 Cookie Session Token相关的知识



返回列表 返回列表
评论

    分享到