07.Cookie

Cookie简介

Cookie是Servlet向Web服务器发送的一些少量信息,这些信息由浏览器保存,然后发送回服务器。Cookie一般用来保存会话ID来实现会话跟踪(jsessionid=xxxxxxxxx)

一个Cookie拥有一个名称、一个值和一些可选的属性,比如注释、路径和域限定符、最大生存时间和版本号。

Servlet通过使用HttpServletResponse的addCookie(cookie)方法将Cookie发送到浏览器,该方法将字段添加到HTTP响应头发送到浏览器。浏览器支持每台Web服务器有20个Cookie,总共有30个Cookie,每个Cookie的大小默认为4kB。

浏览器通过向HTTP请求头添加字段将Cookie返回给Servlet。可使用HTTPServletRequest的getCookies()方法从请求中获取Cookie。

Cookie通过路径和名称来进行区分,可以参考我的另一篇文章:Cookie的作用域。

Cookie常用方法

  • Cookie(String name, String value):构建通过key/value保存信息(注意都是String类型)。

  • void setDomain(String pattern):指定应在其中显示此Cookie的域。

  • String getDomain():返回此Cookie设置的域名。

  • void setMaxAge(int expiry):设置Cookie的最大生存时间,以秒为单位。负值表示浏览器退出时删除,0值则会导致立马删除Cookie。

  • int getMaxAge():返回以秒为单位指定的Cookie的最大生存时间。

  • String getName():返回Cookie的名称。名称在创建之后不得更改,否则将被覆盖。

  • String getValue():返回Cookie的值。

  • void setPath(String uri):指定客户端应该返回Cookie的路径。对于指定目录中的所有页面以及该目录子目录中的所有页面都是可见的。

使用Cookie

  • 在服务器端添加Cookie

  • 在服务器端获取Cookie

  • 删除Cookie

  • 客户端禁用Cookie

程序示例

工程名称:SessionTrack

HTML文件(cookietest.html)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

    <p>
    <a href="save">保存Cookie</a>
    </p>
    <p>
    <a href="temp/read">读取Cookie</a>
    </p>
    <p>
    <a href="remove">移除Cookie</a>
    </p>

</body>
</html>

保存Cookie(SaveCookieServlet.java)

package com.li.servlet.cookie;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SaveCookieServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Cookie c1=new Cookie("test1", "test1value");
        resp.addCookie(c1);
        //不设置路径表示cookie的路径在我们当前的Servlet配置路径下

        Cookie c2=new Cookie("test2", "test2value");
        //这个斜杠表示我们当前工程的根目录,表示任意应用都可以访问
        c2.setPath("/");
        resp.addCookie(c2);

        Cookie c3=new Cookie("test3", "test3value");
        //这个斜杠表示我们当前工程的根目录下的temp文件下,只对该目录及其子目录可见
        c3.setPath("/SessionTrack/temp/");
        resp.addCookie(c3);

        /*保存到Cookie我们也可以在浏览器中查看,并查看其值*/

        resp.sendRedirect("cookietest.html");
    }
}

读取Cookie(ReadCookieServlet.java)

package com.li.servlet.cookie;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ReadCookieServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        //获取所有Cookie数组(之前的第三个Cookie获取不到,因为路径不同)
        //要想读取第三个Cookie,需要将服务配置到Cookie的可见目录下(web.xml)
        Cookie[] cookies=req.getCookies();
        StringBuilder sb=new StringBuilder("<h3>Cookie信息:</h3>");

        for (Cookie c : cookies) {
            sb.append("<li>").append(c.getName()).append("->").append(c.getValue()).append("</li>");

        }

        //设置内容类型
        resp.setContentType("text/html; charset=UTF-8");
        resp.getWriter().write(sb.toString());

    }
}

移除Cookie(RemoveCookieServlet.java)

package com.li.servlet.cookie;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*通过更改生命周期的方式来删除Cookie*/

public class RemoveCookieServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //删除保存到c1Cookie,设置生存时间为零秒即可
        //name值只有一个,新建相同name的cookie相当于更新
        Cookie c1=new Cookie("test1", "test1value");
        c1.setMaxAge(0);
        resp.addCookie(c1);
        resp.sendRedirect("cookietest.html");
    }

}

配置文件(web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>SessionTrack</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

  <!-- Cookie配置 -->
  <servlet>
    <servlet-name>SaveCookie</servlet-name>
    <servlet-class>com.li.servlet.cookie.SaveCookieServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SaveCookie</servlet-name>
    <url-pattern>/save</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>ReadCookie</servlet-name>
    <servlet-class>com.li.servlet.cookie.ReadCookieServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ReadCookie</servlet-name>
    <url-pattern>/temp/read</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>RemoveCookie</servlet-name>
    <servlet-class>com.li.servlet.cookie.RemoveCookieServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>RemoveCookie</servlet-name>
    <url-pattern>/remove</url-pattern>
  </servlet-mapping>

</web-app>

URL重写

为什么要对URL进行重写?

  • 客户端不支持Cookie或者禁用Cookie。

  • 服务器端不能通过Cookie获取jsessionid

URL重写

  • 将jsessionid加入到URL之后。

  • 使用HttpServletResponse重写

    • String encodeURL(String URL):通过将会话ID包含在指定URL中并对该URL进行编码。如果不需要编码,则返回未更改的URL。

    • String encodeRedrectURL(String url):对指定的URL进行编码,以便在sendRedirect方法中使用它,如果不需要编码,则返回未更改的URL(可判断是否需要将ID加入URL)

程序示例

请参考我的另一篇博客:HttpSession
这里有我使用session验证登录的程序,下面的程序只是对这个程序做了一些更改。

对于我们用session来验证登录的程序,如果我们在浏览器禁用Cookie,那我们便永远通过session来访问服务,会一直出现在登录页面

验证登录(LoginServlet)
通过重写URL,当我们登录时,我们把鼠标悬在返回首页的链接上,可以发现,jsessionid被加载链接的URL后面。

package com.li.servlet;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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;

@WebServlet("/pages/login")
public class LoginServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String name=req.getParameter("name");
        String password=req.getParameter("password");
        if("admin".equals(name) && "123456".equals(password)) {
            //获取会话
            HttpSession session=req.getSession();
            session.setAttribute("uesr", name);
            resp.setContentType("text/html;charset=UTF-8");

            /*URL重写,解析出重写的部分*/
            String encodeURL="";
            Pattern pattern = Pattern.compile(";\\S+");
            Matcher m = pattern.matcher(resp.encodeURL("../index.jsp"));
            while(m.find()) {
                encodeURL=m.group();
            }

            /*放入ServletContext中,在EL表达式通过applicationScope域获取*/
            getServletContext().setAttribute("encodeURL", encodeURL);

            resp.getWriter().write("<strong>欢迎"+name+"!</strong><br/><a href='"+resp.encodeURL("../index.jsp")+"'>返回首页</a>");
        }
        else {
            /*由于我们在配置文件中已经把服务配置到pages文件下,
             *所以,此处我们使用的是相对路径,不在需要加重定向位置所在的文件夹。
             */
            resp.sendRedirect("login.html");
        }
    }
}

主页HTML(index.jsp)

<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>

<body>
    <p>
    <a href="pages/login.html">登录</a>
    </p>

    <p>
    <a href="test${applicationScope.encodeURL }">访问TestServlet(需要登录之后才能访问)</a>
    </p>

    <p>${applicationScope.url }</p>

</body>

</html>

TestServlet服务程序(TestServlet.java)
此程序并未做任何修改

package com.li.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class TestServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //注意参数,session可以为null, 也可以不使用参数从而判断session是否为新的
        HttpSession session=req.getSession(false);
        if(session==null || session.getAttribute("uesr")==null) {
            resp.sendRedirect("../pages/login.html");
            //System.out.println(getContextPath());
        }
        else {
            resp.setContentType("text/html; charset=UTF-8");
            resp.getWriter().write("<h3>欢迎"+session.getAttribute("uesr")+"访问TestServelt</h3><a href='../index.html'>返回首页</a>");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
伪造flask的cookie需要进行以下步骤: 1. 首先,获取SECRET_KEY。可以通过查看网站的源码或配置文件来获取。例如,从一个名为config.py的文件找到SECRET_KEY的值为"ckj123" 。 2. 使用该SECRET_KEY以及其他必要的信息来构造一个字典形式的cookie数据。例如,使用一个名为flask-session-cookie-manager的工具对获得的cookie进行解码,可以得到一个包含各种字段的字典,如{'_fresh': True, '_id': b'06915654898f790b44e5554613abeebf06a11a8565a1179ac98614a6ef42eb36a441114625646280fbd1521fd582c78886cbcd2831170ae7085fce07cf79e1a6', 'csrf_token': b'39f077fc80de991722159da4b52dd60235d0384e', 'image': b'jM7s', 'name': '123', 'user_id': '11'} 。 3. 使用伪造的cookie信息进行相关操作。可以将伪造的cookie用于请求授权、模拟用户登录或其他需要验证的操作。 需要注意的是,伪造cookie属于非法行为,仅供学习和研究目的使用。在实际应用,请遵守相关法律法规,不要进行任何非法的活动。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [buuctf [HCTF 2018]admin(flask cookie伪造)](https://blog.csdn.net/qq_44111753/article/details/111994906)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值