目录
利用会话管理来模拟实现登录功能与敏感资源的访问,其中用户登录时,验证账号密码是否通过,如果通过,创建session并保存用户信息,对于敏感资源的访问,则通过验证session来实现.
登录页面

账号为空时

密码为空时

当输入错误账号和密码时

当输入正确账号密码
跳转到指定界面

在验证用户所输入的账号密码时,如果账号密码正确,则对其创建session并记录用户信息.

req.getSession(),括号中的状态设置为true,说明获取不到session对象时会自动创建一个,因为是登录功能,所以允许其创建,如果是对敏感资源的访问,就需要将其设置为false了(即如果没有获取到session对象,就不能访问敏感资源).
该功能的实现主要是验证session,首先获取session对象,如果获取到了就继续进行验证,如果未获取到,不能创建session对象,因此需要在req.getSession(),括号中的状态设置为false。

1.登录时,验证账号密码成功:
· 创建session会话,并保存在服务端
· 返回响应头Set-Cookie:sessionId=xxx
2.客户端保存Cookie信息在本地
3.客户端每次请求都会自动携带Cookie请求头
4.服务端就可以通过sessionId找到是哪个用户的会话
首先,输入正确的账号密码,利用抓包工具对其抓包.

可以看出客户端成功了发送账号与密码,服务端也返回给客户端了响应,此时的状态是登录状态,因此可以对敏感资源进行访问

在抓包访问sensitive.html时,可以看出此时访问该网页的Cookie与验证成功登录后创建的Cookie是一致的.
通过以下步骤清楚网页保存的Cookie信息,清除后再尝试访问sensitive.html,通过抓包观察其细节.


在删除Cookie信息后,在对该网页进行访问.
通过抓包工具,可以看出此时对sensitive.html文件访问时不存在Cookie信息
因此,通过Session和Cookie会话管理机制就可以实现登录功能,并利用其控制未登录状态和登录状态可以访问到的资源区别,后续会更新Session和Cookie详细分析文章.
- package org.example.demo;
-
- /**
- * Created with IntelliJ IDEA.
- * Description:
- * User: Li_yizYa
- * Date: 2022—06—22
- * Time: 20:53
- */
- public class User {
- private String username;
- private String password;
-
- @Override
- public String toString() {
- return "User{" +
- "username='" + username + '\'' +
- ", password='" + password + '\'' +
- '}';
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
- }
- package org.example.demo;
-
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * Created with IntelliJ IDEA.
- * Description:
- * User: Li_yizYa
- * Date: 2022—06—22
- * Time: 12:36
- */
- @WebServlet("/login")
- public class LoginServlet extends HttpServlet {
- private static final ObjectMapper M = new ObjectMapper();
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //获取请求数据: json格式
- req.setCharacterEncoding("UTF-8");
- //反序列化: 将json对象转化为Java对象
- User user = M.readValue(req.getInputStream(),User.class);
- //验证账号密码,验证的结果设置一个对象,再转换为json字符串返回客户端
- Map<String, Object> objectMap = new HashMap<>();
- //验证通过
- if("lyz".equals(user.getUsername()) && "1425".equals(user.getPassword())) {
- objectMap.put("ok",true);
- //创建session用户会话(本身是获取session,传入boolean == true,获取不到会创建一个)
- HttpSession session = req.getSession(true);
- //使用session来保护用户信息
- session.setAttribute("user", user);
- //验证失败
- }else {
- objectMap.put("ok",false);
- objectMap.put("msg","账号或密码错误");
- }
- //返回响应: 设置数据格式和编码
- resp.setContentType("application/json");
- resp.setCharacterEncoding("UTF-8");
- resp.getWriter().write(M.writeValueAsString(objectMap));
- }
- }
- package org.example.demo;
-
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * Created with IntelliJ IDEA.
- * Description:
- * User: Li_yizYa
- * Date: 2022—06—22
- * Time: 20:53
- */
- @WebServlet("/sensitive")
- public class SensitiveServlet extends HttpServlet {
- private static final ObjectMapper M = new ObjectMapper();
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //验证用户身份: ①获取session(获取不到不能创建); ②验证session和其中的user
- HttpSession session = req.getSession(false);
- if(session != null) {
- User user = (User)session.getAttribute("user");
- if(user != null) {
- Map<String, Object> map = new HashMap<>();
- map.put("a","恭喜你,成功登录");
- map.put("b","十分欢迎您");
- resp.setContentType("application/json");
- resp.setCharacterEncoding("UTF-8");
- resp.getWriter().write(M.writeValueAsString(map));
- return;
- }
- }
- //其他情况返回401状态码,表示未登录
- resp.setStatus(401);
- }
- }
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>登陆页面</title>
- <link rel="stylesheet" href="css/login.css">
- </head>
- <body>
- <div>
- <div id="login-container">
- <div id="login-form">
- <h3>登录 页面</h3>
- <div class="login-row">
- <span>用户名</span>
- <input type="test" id="username">
- </div>
- <div class="login-row">
- <span>密码</span>
- <input type="password" id="password">
- </div>
- <div class="login-row">
- <input type="submit" id="submit" value="登录">
- </div>
- </div>
- </div>
- </div>
- </body>
-
-
- <script src="util.js"></script>
- <script>
- var btn = document.querySelector("#submit");
- var username = document.querySelector("#username");
- var password = document.querySelector("#password");
-
-
- btn.onclick = function(){
- if(!username.value){
- alert("账号不能为空")
- return;
- }
- if(!password.value){
- alert("密码不能为空")
- return;
- }
- ajax({
- method: "POST",
- url: "login",
- contentType: "application/json",
- body: JSON.stringify({
- username: username.value,
- password: password.value,
- }),
- callback: function(status, resp){
- if(status == 200){
- //转换响应正文(json字符串)为json对象
- var body = JSON.parse(resp);
- if(body.ok){//登陆成功
- location.href = "sensitive.html";
- }else{//登陆失败
- alert("登陆失败:" + body.msg);
- }
- }else{
- alert("状态码:" + status);
- }
- }
- })
- }
- </script>
-
- </html>
-
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <style>
- ul {
- text-align: center;
- color: brown;
- margin-bottom: 50px;
- }
- </style>
- </head>
- <body>
- <ul></ul>
- <script src="util.js"></script>
- <script>
- var ul = document.querySelector("ul");
- //会话管理: 没有登陆不允许访问
- //前端html、css、js全部开放,控制后端即可
- ajax({
- method: "GET",
- url: "sensitive",
- callback: function(status, resp){
- if(status == 200){
- var body = JSON.parse(resp);
- var content = ' ';
- content += `<li>键a: ${body.a}</li>`;
- content += `<li>键b: ${body.b}</li>`;
- ul.innerHTML = content;
- }else{
- alert("响应状态码" + status)
- }
- }
- })
- </script>
- </body>
- </html>
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
- #login-container {
- height: calc(100% - 50px);
- display: flex;
- justify-content: center;
- align-items: center;
- }
-
- #login-form {
- width: 400px;
- background-color: cornflowerblue;
- border-radius: 10px;
- padding: 50px 50px 100px 50px;
- }
-
- #login-form>h3 {
- text-align: center;
- margin-bottom: 50px;
- }
-
- #login-form>.login-row {
- height: 50px;
- display: flex;
- }
- #login-form>.login-row>span {
- height: 40px;
- line-height: 40px;
- width: 100px;
- font-weight: 500;
- }
- #username,
- #password {
- height: 40px;
- width: 200px;
- border-radius: 5px;
- border: none;
- outline: none;
- }
- #submit {
- width: 100%;
- height: 40px;
- background-color: green;
- color: white;
- border-radius: 5px;
- border: none;
- }
- #submit:active {
- background-color: gray;
- }
- // 参数 args 是一个 JS 对象, 里面包含了以下属性
- // method: 请求方法
- // url: 请求路径
- // body: 请求的正文数据
- // contentType: 请求正文的格式
- // callback: 处理响应的回调函数, 有两个参数, 响应正文和响应的状态码
- function ajax(args) {
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function () {
- // 0: 请求未初始化
- // 1: 服务器连接已建立
- // 2: 请求已接收
- // 3: 请求处理中
- // 4: 请求已完成,且响应已就绪
- if (xhr.readyState == 4) {
- args.callback(xhr.status, xhr.responseText)
- }
- }
- xhr.open(args.method, args.url);
- if (args.contentType) {
- xhr.setRequestHeader('Content-type', args.contentType);
- }
- if (args.body) {
- xhr.send(args.body);
- } else {
- xhr.send();
- }
- }