【Java-Web】利用Session和Filter进行权限管理
创始人
2024-02-24 00:08:53
0

目录

1.Cookie

概念

优势和不足

2.Session

3.用Session实现登陆

概念

代码

4.使用Filter实现过滤


        在使用浏览器的时候,浏览器如何保存我们的个人信息呢?有两种方法,一个是Cookie,一个是Session,区别在于,前者是在客户端保存,即我们的电脑或手机等设备上本地保存;后者是在服务器端保存,不需要占用我们本地的空间。两者共同点是都有一个保存期限。比如使用Session的网页,登陆一个网站,第一次登陆之后,可能后面几天不需要再次登录,进去就是自己的页面,但是再过一段时间会提示身份验证过期,需要重新登陆,这就是服务器端的Session保存期限到了,销毁了。

1.Cookie

概念

        cookie的作用是把信息存在客户端,然后通过用户的访问传给服务器。

        如下,第一次访问的时候,客户端向服务器端发送第一次请求request1,服务器端收到之后,返回第一次请求response1,并且返回cookies,expire(cookie的期限)等信息,客户端收到这些信息之后,在本地创建cookies。在后面的一次次request请求中,客户端会携带着cookies一起发送请求,然后服务器端也会更新cookies并返回。

        此外,除了服务器端建立cookies信息,也可以通过JavaScript,在服务器端创建cookies。

        如下,通过网页的开发人员工具,可以看到cookie信息。

        也可以看到,在浏览器设置里面的,针对cookie有许许多多的设置。

优势和不足

        cookie是在本地创建,所以不需要占用服务器的资源

        但是与此同时,如果我们清除了本地的cookie,那么它就不存在了。比如,一个使用cookie的网站,第一次登录之后,选择七天免账号密码登陆,然后第二天,我把浏览器的cookie等等数据清除了,清除之后再次登陆,发现不是免账号密码,还是需要重新登陆,这就是因为cookie数据被清除,服务器端无法读取对应信息。

        此外,使用cookie其实安全性并不高,上面说到,cookie可以在客户端修改,那么如果一些别有用心的黑客通过修改cookie来欺骗服务器,对服务器端构成威胁。

        所以,现在很多网站使用cookie不是那么多。

2.Session

        相较cookie,session(会话)的安全性更高。其将信息存储在了服务器端。

        在客户端向服务器端发送request之后,服务器端会返回response,同时返回一个id号,并且在服务器端的内存开辟空间,存储这个id和相关data 。这个id号是标识了当前用户的。在该用户接下来的每一次访问,都会带着这个id,服务器端都会在内存里查找这个id是否存在。而和这个用户相关的信息,也是存储在服务器端。当然,Session也是有时间限制,只要服务器端对应的 id 没有过期,这个会话就还保留着。

        典型的例子是,去网上购物商城买东西,在第一个网店买了本书,加入购物车;第二个网店买鞋子,加入购物车;第三个网店买衣服,加入购物车。最后结算的时候是一起结算的。很明显,访问的是三个不同的网店,但是结帐的时候它怎么会知道我选了哪些商品?明显有一个地方存储我的这些信息,这个地方就是服务器端。

        如下,一次request代表一次请求,一次reponse代表一次返回,而一个会话(Session)是多次请求、返回,反反复复交流才叫一个Session。Session是由很多request和response组成的,而会话的 id 就存在服务器端,对应的信息也存在服务器端。

        这种模型,一方面对于客户端的依赖少了。另一方面,数据存在服务器端,客户端无法修改,安全性更高

3.用Session实现登陆

概念

         在客户端访问的时候,tomcat会自动在服务器端创建一个Session存储相关信息,如下,Actor 1 绑定的 Session 是 1 (圆圈),Actor 2 绑定的 Session 是 2。Session对象和用户的每次访问都是绑定在一起的。

         比如在Session里面创建一个 flag,标记用户是否登陆,如果未登陆就让他登陆,已经登陆,就可以使用网站里的资源,就可以实现我们平常使用的登陆功能。

代码

        创建一个Java类,名字为 LoginServlet.java ,其中的代码如下。

        一些解释也在注释里面。中间用到的UserRepo里面的 auth方法下面放了一张图片。

package cn.edu.swu.inout;import cn.edu.swu.user.User;
import cn.edu.swu.user.UserRepo;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;@WebServlet("/login")
public class LoginServlet extends HttpServlet {public static final String LOGIN_TOKEN="USER_LOGIN_TOKEN";public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {this.doPost(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {String userName = request.getParameter("user");String password = request.getParameter("password");//这里的逻辑是//如果账号密码不为空,那么就直接登陆//如果为空,有可能已经登陆,有可能直接没输入,那么看session,session两种情况,一个是有数据,一个是没有数据//如果没有数据,那么跳到login.html页面//如果有数据,说明之前登陆过,那么直接跳到admin页面if (userName != null && password != null) {//为什么要有这个判断,因为点了登陆之后,他是跳到login的,即这个loginservlet,所以要在这里有this.doLogin(request, response);} else {HttpSession session = request.getSession();if (session == null || session.getAttribute(LoginServlet.LOGIN_TOKEN) != Boolean.TRUE) {response.sendRedirect("./login.html");} else {response.sendRedirect("./admin.html");}}}public void doLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {String userName = request.getParameter("user");String password = request.getParameter("password");try {User user = UserRepo.getInstance().auth(userName, password);if (user != null) {HttpSession session=request.getSession();//创建一个sessionsession.setAttribute(LOGIN_TOKEN,Boolean.TRUE);//这就相当于flag,标记是否登陆,为true则已经登陆,否则未登录response.sendRedirect("./admin.html");} else {response.sendRedirect("./index.html");}} catch (SQLException | IOException e) {throw new RuntimeException(e);}}}

         如下,这个方法就是在数据库里面,通过账号密码 寻找相匹配的用户并返回。

         但是,像这样子些,如果我得到了后台的网页地址,直接输入网址就可以进入,相当于绕过了登陆,并且进行各种操作。这样非常不安全,所以,要使用 Filter 进行过滤。

4.使用Filter实现过滤

        在这里我们进行简单的操作,使用 Filter 对所有资源进行过滤,这样子所有资源都无法直接访问,也包括一些图片资源之类的。当然,像一些图片资源、登陆界面、初始界面等等,可以直接“放行”,不需要对其进行限制。

        除了直接“放行”的资源,其余资源通过Session来判断是否放心。如果没有Session,那么肯定就是未登陆过,就需要登陆。如果有Session,有的网站会一进入就创建Session,所以有两种情况,一种是已经登陆,一种是没有登陆,但是自动创建Session两者区分要用Session里面的flag来判定(flag是上文说过的来标记是否登陆过的信息)。 逻辑和代码如下,由于只是简单模拟,整个逻辑并不特别复杂。

        使用 Filter 进行过滤之后,即使得到了后台网址,也不可以直接访问,要先登录,安全性大大提高。就好比我们平时登陆校园网,如果直接输入同学给的内部链接,不可以直接访问操作界面,跳出来的是登陆界面。

package cn.edu.swu.user;import cn.edu.swu.inout.LoginServlet;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;@WebFilter("/*")
//这里是所有网页都生效
public class AuthFilter extends HttpFilter {public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {HttpSession session = request.getSession();System.out.println("auth filter");String uri = request.getRequestURI();System.out.println(uri);if ( uri.endsWith("login.html") || uri.endsWith("index.html") || uri.endsWith("verifyCode") ||uri.endsWith("png") || uri.endsWith("jpg") || uri.endsWith("css") || uri.endsWith("login")) {chain.doFilter(request, response);return;}if (session == null) {System.out.println("auth failed");response.sendRedirect("./login.html");} else {Boolean toke = (Boolean) session.getAttribute(LoginServlet.LOGIN_TOKEN);if (toke == Boolean.TRUE) {//这里还要判断的原因是,有的网站,即使不登陆也要验证session,所以这里验证一下session里的LOGIN_TOKEN//是否为true,为true则是登陆过,否则未登陆过。因为只有之前登陆正确才会设置它System.out.println("登录验证成功");chain.doFilter(request, response);} else {System.out.println("auth failed");response.sendRedirect("./login.html");}}}}

相关内容

热门资讯

学习贯彻党的二十届四中全会精神... 本报讯 (记者庞慧敏)“工资必须按月足额支付给农民工,任何单位和个人都不得拖欠。”这是广西壮族自治区...
房山综治中心调解超龄劳动者工伤... 新京报讯(记者张静姝)近日,北京市房山区综治中心丁俊宏调解工作室团队成功调解一起超龄劳动者工伤纠纷,...
海南自贸港正式封关 “零关税”... 12月18日,海南自贸港全岛封关运作正式启动。在封关前半个月,《新闻调查》栏目组赴海南拍摄记录,详细...
湖南大学法学院党委书记李劲松到... 2025年12月19日下午,湖南大学长沙校友会“法商共创探讨沙龙”在湖南芙蓉律师事务所44楼大会议室...
从法律咨询到健康关怀:长沙市律... 2025年12月16日至19日,湖南省中医附一医院的高级康复理疗师在湖南芙蓉律师事务所,开展了一场为...
新闻调查丨海南自贸港正式封关 ... 12月18日,海南自贸港全岛封关运作正式启动。在封关前半个月,《新闻调查》栏目组赴海南拍摄记录,详细...
具身智能迎来政策“红利期”,灵... 一台身形庞大的机器人,却拥有一双灵巧的“手”。它可以根据任务指令,用五根手指灵活地拿取物品,精准避障...
明年,山西省将实现政策范围内住... 12月19日,山西省医保局发布消息,我省通过提高保障水平、优化经办服务,切实减轻参保职工生育医疗负担...
南通市海门区:“三及时”制度助... “一名机关干部因房屋漏水与邻里产生矛盾,社区监督员第一时间反馈后,镇上组织部门迅速介入提醒该干部并协...
涉外企业跨境金融服务政策宣讲会... 本报讯(记者 安欣欣)12月19日,由郑州市委金融委员会办公室、中国人民银行河南省分行联合举办的涉外...