• JavaWeb~利用会话管理(基于Session+Cookie)来模拟实现用户登录以及敏感资源的访问


    目录

    界面展示

    Session的作用

    登陆功能

     敏感资源的访问

    主要流程 

    访问敏感资源示例

    登陆状态时

    未登录状态

    完整代码

    后端代码

    User类

    LoginServlet.java

    SensitiveServlet.java

    前端代码

    login.html

    sensitive.html

    login.css

    util.js


    利用会话管理来模拟实现登录功能与敏感资源的访问,其中用户登录时,验证账号密码是否通过,如果通过,创建session并保存用户信息,对于敏感资源的访问,则通过验证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详细分析文章.

    完整代码

    后端代码

    User类

    1. package org.example.demo;
    2. /**
    3. * Created with IntelliJ IDEA.
    4. * Description:
    5. * User: Li_yizYa
    6. * Date: 2022—06—22
    7. * Time: 20:53
    8. */
    9. public class User {
    10. private String username;
    11. private String password;
    12. @Override
    13. public String toString() {
    14. return "User{" +
    15. "username='" + username + '\'' +
    16. ", password='" + password + '\'' +
    17. '}';
    18. }
    19. public String getUsername() {
    20. return username;
    21. }
    22. public void setUsername(String username) {
    23. this.username = username;
    24. }
    25. public String getPassword() {
    26. return password;
    27. }
    28. public void setPassword(String password) {
    29. this.password = password;
    30. }
    31. }

    LoginServlet.java

    1. package org.example.demo;
    2. import com.fasterxml.jackson.databind.ObjectMapper;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import javax.servlet.http.HttpSession;
    9. import java.io.IOException;
    10. import java.util.HashMap;
    11. import java.util.Map;
    12. /**
    13. * Created with IntelliJ IDEA.
    14. * Description:
    15. * User: Li_yizYa
    16. * Date: 2022—06—22
    17. * Time: 12:36
    18. */
    19. @WebServlet("/login")
    20. public class LoginServlet extends HttpServlet {
    21. private static final ObjectMapper M = new ObjectMapper();
    22. @Override
    23. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    24. //获取请求数据: json格式
    25. req.setCharacterEncoding("UTF-8");
    26. //反序列化: 将json对象转化为Java对象
    27. User user = M.readValue(req.getInputStream(),User.class);
    28. //验证账号密码,验证的结果设置一个对象,再转换为json字符串返回客户端
    29. Map<String, Object> objectMap = new HashMap<>();
    30. //验证通过
    31. if("lyz".equals(user.getUsername()) && "1425".equals(user.getPassword())) {
    32. objectMap.put("ok",true);
    33. //创建session用户会话(本身是获取session,传入boolean == true,获取不到会创建一个)
    34. HttpSession session = req.getSession(true);
    35. //使用session来保护用户信息
    36. session.setAttribute("user", user);
    37. //验证失败
    38. }else {
    39. objectMap.put("ok",false);
    40. objectMap.put("msg","账号或密码错误");
    41. }
    42. //返回响应: 设置数据格式和编码
    43. resp.setContentType("application/json");
    44. resp.setCharacterEncoding("UTF-8");
    45. resp.getWriter().write(M.writeValueAsString(objectMap));
    46. }
    47. }

    SensitiveServlet.java

    1. package org.example.demo;
    2. import com.fasterxml.jackson.databind.ObjectMapper;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import javax.servlet.http.HttpSession;
    9. import java.io.IOException;
    10. import java.util.HashMap;
    11. import java.util.Map;
    12. /**
    13. * Created with IntelliJ IDEA.
    14. * Description:
    15. * User: Li_yizYa
    16. * Date: 2022—06—22
    17. * Time: 20:53
    18. */
    19. @WebServlet("/sensitive")
    20. public class SensitiveServlet extends HttpServlet {
    21. private static final ObjectMapper M = new ObjectMapper();
    22. @Override
    23. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    24. //验证用户身份: ①获取session(获取不到不能创建); ②验证session和其中的user
    25. HttpSession session = req.getSession(false);
    26. if(session != null) {
    27. User user = (User)session.getAttribute("user");
    28. if(user != null) {
    29. Map<String, Object> map = new HashMap<>();
    30. map.put("a","恭喜你,成功登录");
    31. map.put("b","十分欢迎您");
    32. resp.setContentType("application/json");
    33. resp.setCharacterEncoding("UTF-8");
    34. resp.getWriter().write(M.writeValueAsString(map));
    35. return;
    36. }
    37. }
    38. //其他情况返回401状态码,表示未登录
    39. resp.setStatus(401);
    40. }
    41. }

     

    前端代码

    login.html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>登陆页面</title>
    8. <link rel="stylesheet" href="css/login.css">
    9. </head>
    10. <body>
    11. <div>
    12. <div id="login-container">
    13. <div id="login-form">
    14. <h3>登录 页面</h3>
    15. <div class="login-row">
    16. <span>用户名</span>
    17. <input type="test" id="username">
    18. </div>
    19. <div class="login-row">
    20. <span>密码</span>
    21. <input type="password" id="password">
    22. </div>
    23. <div class="login-row">
    24. <input type="submit" id="submit" value="登录">
    25. </div>
    26. </div>
    27. </div>
    28. </div>
    29. </body>
    30. <script src="util.js"></script>
    31. <script>
    32. var btn = document.querySelector("#submit");
    33. var username = document.querySelector("#username");
    34. var password = document.querySelector("#password");
    35. btn.onclick = function(){
    36. if(!username.value){
    37. alert("账号不能为空")
    38. return;
    39. }
    40. if(!password.value){
    41. alert("密码不能为空")
    42. return;
    43. }
    44. ajax({
    45. method: "POST",
    46. url: "login",
    47. contentType: "application/json",
    48. body: JSON.stringify({
    49. username: username.value,
    50. password: password.value,
    51. }),
    52. callback: function(status, resp){
    53. if(status == 200){
    54. //转换响应正文(json字符串)为json对象
    55. var body = JSON.parse(resp);
    56. if(body.ok){//登陆成功
    57. location.href = "sensitive.html";
    58. }else{//登陆失败
    59. alert("登陆失败:" + body.msg);
    60. }
    61. }else{
    62. alert("状态码:" + status);
    63. }
    64. }
    65. })
    66. }
    67. </script>
    68. </html>

    sensitive.html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. <style>
    9. ul {
    10. text-align: center;
    11. color: brown;
    12. margin-bottom: 50px;
    13. }
    14. </style>
    15. </head>
    16. <body>
    17. <ul></ul>
    18. <script src="util.js"></script>
    19. <script>
    20. var ul = document.querySelector("ul");
    21. //会话管理: 没有登陆不允许访问
    22. //前端html、css、js全部开放,控制后端即可
    23. ajax({
    24. method: "GET",
    25. url: "sensitive",
    26. callback: function(status, resp){
    27. if(status == 200){
    28. var body = JSON.parse(resp);
    29. var content = ' ';
    30. content += `<li>键a: ${body.a}</li>`;
    31. content += `<li>键b: ${body.b}</li>`;
    32. ul.innerHTML = content;
    33. }else{
    34. alert("响应状态码" + status)
    35. }
    36. }
    37. })
    38. </script>
    39. </body>
    40. </html>

    login.css

    1. * {
    2. margin: 0;
    3. padding: 0;
    4. box-sizing: border-box;
    5. }
    6. #login-container {
    7. height: calc(100% - 50px);
    8. display: flex;
    9. justify-content: center;
    10. align-items: center;
    11. }
    12. #login-form {
    13. width: 400px;
    14. background-color: cornflowerblue;
    15. border-radius: 10px;
    16. padding: 50px 50px 100px 50px;
    17. }
    18. #login-form>h3 {
    19. text-align: center;
    20. margin-bottom: 50px;
    21. }
    22. #login-form>.login-row {
    23. height: 50px;
    24. display: flex;
    25. }
    26. #login-form>.login-row>span {
    27. height: 40px;
    28. line-height: 40px;
    29. width: 100px;
    30. font-weight: 500;
    31. }
    32. #username,
    33. #password {
    34. height: 40px;
    35. width: 200px;
    36. border-radius: 5px;
    37. border: none;
    38. outline: none;
    39. }
    40. #submit {
    41. width: 100%;
    42. height: 40px;
    43. background-color: green;
    44. color: white;
    45. border-radius: 5px;
    46. border: none;
    47. }
    48. #submit:active {
    49. background-color: gray;
    50. }

    util.js

    1. // 参数 args 是一个 JS 对象, 里面包含了以下属性
    2. // method: 请求方法
    3. // url: 请求路径
    4. // body: 请求的正文数据
    5. // contentType: 请求正文的格式
    6. // callback: 处理响应的回调函数, 有两个参数, 响应正文和响应的状态码
    7. function ajax(args) {
    8. var xhr = new XMLHttpRequest();
    9. xhr.onreadystatechange = function () {
    10. // 0: 请求未初始化
    11. // 1: 服务器连接已建立
    12. // 2: 请求已接收
    13. // 3: 请求处理中
    14. // 4: 请求已完成,且响应已就绪
    15. if (xhr.readyState == 4) {
    16. args.callback(xhr.status, xhr.responseText)
    17. }
    18. }
    19. xhr.open(args.method, args.url);
    20. if (args.contentType) {
    21. xhr.setRequestHeader('Content-type', args.contentType);
    22. }
    23. if (args.body) {
    24. xhr.send(args.body);
    25. } else {
    26. xhr.send();
    27. }
    28. }

  • 相关阅读:
    12 mysql char/varchar 的数据存储
    基于 Vite + Vue3 的组件库打包并发布到npm
    原创 VTK 基础入门 ( 一 ) 贴纹理
    常用的Visual Studio快捷键
    SpringBoot中企业微信的API调用
    计算机指令
    Flink-经典案例WordCount快速上手以及安装部署
    C/C++数据结构题目(2022)
    报错解决:Process finished with exit code -1073741819 (0xC0000005)
    如何解决 IntelliJ IDEA 2024 启动总闪退问题?一站式解决方案!
  • 原文地址:https://blog.csdn.net/qq_58284486/article/details/125363920