23

这是一个设置 cookie 的函数:

public void addCookie(String cookieName, String cookieValue, Integer maxAge, HttpServletResponse response) {
    Cookie cookie = new Cookie(cookieName, cookieValue);
    cookie.setPath("/mycampaigns");
    cookie.setSecure(isSecureCookie);
    cookie.setMaxAge(maxAge);
    response.addCookie(cookie);
}

我相信 servlet 3.0,有办法直接做到这一点。不幸的是,我的组织使用 2.5,此时升级不是一种选择。

有没有办法使用响应来设置cookie?这是我在网上找到的一个例子

response.setHeader("SET-COOKIE", "[SOME STUFF]" +"; HttpOnly")

如果这是做我想做的唯一方法,我会用什么替换“[SOME STUFF]”,这样我就不会丢失我的函数当前存储在 cookie 中的任何数据?

4

9 回答 9

9

你是对的,手动设置标题是实现目标的正确方法。

您还可以使用 javax.ws.rs.core.NewCookie 或任何其他具有有用 toString 方法的类将 cookie 打印到标头以使事情更简单。

public static String getHttpOnlyCookieHeader(Cookie cookie) {

    NewCookie newCookie = new NewCookie(cookie.getName(), cookie.getValue(), 
            cookie.getPath(), cookie.getDomain(), cookie.getVersion(), 
            cookie.getComment(), cookie.getMaxAge(), cookie.getSecure());

    return newCookie + "; HttpOnly";
}

以及用法:

response.setHeader("SET-COOKIE", getHttpOnlyCookieHeader(myOriginalCookie));
于 2014-03-21T02:51:56.753 回答
4

此代码无需使用即可工作response.setHeader()

public void addCookie(String cookieName, String cookieValue, Integer maxAge, HttpServletResponse response) {  
    Cookie cookie = new Cookie(cookieName, cookieValue);
    cookie.setPath("; HttpOnly;");
    cookie.setSecure(isSecureCookie);
    cookie.setMaxAge(maxAge);
    response.addCookie(cookie);
}
于 2014-08-05T14:26:24.353 回答
4

对于 JEE 6 之前的 Java Enterprise Edition 版本,比如 Servlet 2.5,您可以在 OWASP 上找到解决方法。下面是一个例子:

    /**
     * Issue a cookie to the browser
     * 
     * @param response
     * @param cookieName
     * @param cookieValue
     * @param cookiePath
     * @param maxAgeInSeconds
     */
    public static void issueCookieHttpOnly(HttpServletResponse response, 
            String cookieName, 
            String cookieValue, 
            String cookiePath, 
            long maxAgeInSeconds) {

        Date expireDate= new Date();
        expireDate.setTime (expireDate.getTime() + (1000 * maxAgeInSeconds));
        // The following pattern does not work for IE.
        // DateFormat df = new SimpleDateFormat("dd MMM yyyy kk:mm:ss z");

        // This pattern works for Firefox, Chrome, Safari and Opera, as well as IE.
        DateFormat df = new SimpleDateFormat("EEE, dd-MMM-yyyy kk:mm:ss z");
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        String cookieExpire = df.format(expireDate);

        StringBuilder sb = new StringBuilder(cookieName);
        sb.append("=");
        sb.append(cookieValue);
        sb.append(";expires=");
        sb.append(cookieExpire);
        sb.append(";path=");
        sb.append(cookiePath);
        sb.append(";HttpOnly");

        response.setHeader("SET-COOKIE", sb.toString());
    }
于 2015-05-27T16:42:39.173 回答
4

如果您不想使用:

response.addHeader("Set-Cookie","name=value; HttpOnly");

那么您可以在servlet 2.5中使用以下代码。它将在chromefirefoxIE11中完美运行。

Cookie cookie = new Cookie(cookieName, cookieValue);

cookie.setPath(";Path=/;HttpOnly;");
cookie.setSecure(isSecureCookie);
cookie.setMaxAge(maxAge);

response.addCookie(cookie);

注意:如您所知,我们在servlet 2.5版本中没有setHttpOnly()方法,因此您可以使用以下方法代替:

setPath(";Path=/;HttpOnly;");

它将使用路径“ / ”创建一个 cookie,并将Cookie设置为HttpOnly

于 2017-01-25T15:17:29.640 回答
3

对于 Servlet API 2.5,您可以使用

response.addHeader("Set-Cookie","name=value; HttpOnly");

使用 response.setHeader() 时要小心,因为它会删除所有其他 cookie,例如 JSESSIONID cookie。

于 2016-01-18T16:24:34.673 回答
1

如果您不想硬编码HttpOnly;或不喜欢添加标头,请像这样使用apache shiro

void addCookie(javax.servlet.http.Cookie httpCookie,
               HttpServletRequest request,
               HttpServletResponse response) {
    org.apache.shiro.web.servlet.Cookie cookie =
                 new org.apache.shiro.web.servlet.SimpleCookie(httpCookie.getName());

    cookie.setValue(httpCookie.getValue());
    cookie.setPath(httpCookie.getPath());
    // set other stuff from the original httpCookie
    cookie.setHttpOnly(true);

    cookie.saveTo(request, response);
}
于 2017-04-18T06:46:18.613 回答
1

Spring 使用反射来做到这一点,而不会破坏 servlet 2.5 容器。

Method setHttpOnlyMethod = ReflectionUtils.findMethod(Cookie.class, "setHttpOnly", boolean.class);
if (setHttpOnlyMethod != null) {
    ReflectionUtils.invokeMethod(setHttpOnlyMethod, cookie, Boolean.TRUE);      
}

但是 setHttpOnly 方法仅适用于 Servlet 3.0 及更高版本。

于 2016-06-03T09:57:38.933 回答
0

@Yuci 给响应头添加cookie的例子在我的环境中有一些失败。主要是日期格式错误,如果您addHeader不删除其他 cookie,如setHeader. 所以这是我使用 Servlet API 2.5 设置HttpOnlySecurecookie 的工作代码:

public static void addHttpOnlyCookie(HttpServletResponse response,
                                     String cookieName,
                                     String cookieValue,
                                     String cookiePath,
                                     long maxAgeInSeconds) {

    Date expireDate = new Date();
    expireDate.setTime(expireDate.getTime() + 1000L * maxAgeInSeconds);
    DateFormat df = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
    df.setTimeZone(TimeZone.getTimeZone("GMT"));
    String cookieExpire = df.format(expireDate);

    StringBuilder sb = new StringBuilder(cookieName);
    sb.append("=");
    sb.append(cookieValue);
    sb.append("; Expires=");
    sb.append(cookieExpire);
    sb.append("; Path=");
    sb.append(cookiePath);
    sb.append("; Secure; HttpOnly");

    response.addHeader("SET-COOKIE", sb.toString());
}

请注意,这些setPath黑客绝对行不通。不要这样做,它们不适用于 Safari cookie.setPath(";HttpOnly;");:. <= 错误

于 2021-06-26T08:58:55.900 回答
-1
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setPath("/");
cookie.setMaxAge(-1);
response.addCookie(cookie);

实际上在我的情况下,这段代码不能完全正常工作。
路径值不是"/"

但是添加这个cookie.setComment("; HttpOnly;");效果很好!

于 2017-02-09T09:09:37.423 回答