Expires string in cookie header

倾然丶 夕夏残阳落幕 提交于 2020-02-19 09:36:27

问题


Simple question I think, but I just can't seem to find an answer.

I am writing a cookie in a Java Servlet with the Cookie class which is sent to the browser in the response headers like the following:

Set-Cookie: test=somevalue; Domain=.mydomain.org; Expires=Thu, 06-Jan-2011 18:45:20 GMT; Path=/

I am doing this via the Cookie class in the Servlet 2.5 API. I need to add "HTTPOnly" to the end of this String, which the Servlet 2.5 API does not support. No problem, I'll just create the String manually and append "HTTPOnly" to the end...

However, in doing so, the challenge I ran into is that to set the "Expires" header there in the first place, I used .setMaxAge(3600), which creates the "Expires" part of that String. However, since I can't use the Cookie class, I need to create the value of of that "Expires" portion.

So basically, how can I make "3600" formatted to "Thu, 06-Jan-2011 18:45:20 GMT"?

Note: I could probably figure out the correct pattern with DateFormat, but I was hoping there was a better way to do it. Another thought: Use the Cookie class as before then just convert the Cookie into the corresponding header string programatically, then just append "HTTPOnly" to the end. But I am not aware of any way to take the Cookie object and convert it to the corresponding String value.

So optionally, how can I take a Cookie object and convert it to the corresponding String value programatically?

Thanks!


回答1:


Something like this :

Date expdate = new Date ();
expdate.setTime (expdate.getTime() + (3600 * 1000));
String cookieExpire = "expires=" + expdate.toGMTString();
...

.. and since toGMTString() is deprecated

Date expdate= new Date();
expdate.setTime (expdate.getTime() + (3600 * 1000));
DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", java.util.Locale.US);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
String cookieExpire = "expires=" + df.format(expdate);



回答2:


Java 8 now supplies an appropriate date formatter, DateTimeFormatter.RFC_1123_DATE_TIME:

OffsetDateTime oneHourFromNow 
        = OffsetDateTime.now(ZoneOffset.UTC)
        .plus(Duration.ofHours(1));

String cookieExpires 
        = DateTimeFormatter.RFC_1123_DATE_TIME
        .format(oneHourFromNow);

// E.g. "Tue, 8 Nov 2016 20:15:46 GMT"

This format is valid for the the expires attribute, see RFC 6265 § 4.1.1, which defines the format to be an RFC 1123 date:

expires-av        = "Expires=" sane-cookie-date
sane-cookie-date  = <rfc1123-date, defined in [RFC2616], Section 3.3.1>



回答3:


Well, I haven't seen much activity on this question, so I'm going to attempt to answer this in order to provide help to anyone looking for an answer in the future. However, I'll leave it open to give others an opportunity to jump in if they choose.

So there were a couple of options that I considered...

1)

Apache Commons HTTPClient project has a "DateUtil" class that I was hoping would work. http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/util/DateUtil.html. This provides convenience methods to format the date into a few standard formats to communicate dates in http headers... however, none of them seemed to match exactly what was being returned by the servlet container.

2)

Apache Commons also has a Cookie class in that project, which has a "toExternalForm" method that returns a String. Using that, I thought I may have been able to just create the cookie per usual, call "toExternalForm", then append "HTTPOnly". http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/Cookie.html. That might work, but I didn't bother trying.

3)

I finally decided just to use a pattern that matched what my Servlet container was returning, regardless of whether it was a standard format or not. If it is what the Servlet container returns, then it should work, right? Why not...

SimpleDateFormat COOKIE_EXPIRES_HEADER_FORMAT = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss zzz");
COOKIE_EXPIRES_HEADER_FORMAT.setTimeZone(new SimpleTimeZone(0, "GMT"));
Date d = new Date();
d.setTime(d.getTime() + 3600 * 1000); //1 hour
String cookieLifeTime = COOKIE_EXPIRES_HEADER_FORMAT.format(d);
response.setHeader("Set-Cookie", "test=somevalue; Domain=.mydomain.org; Expires=" + cookieLifeTime + "; Path=/; HTTPOnly");



回答4:


The first answer given by JasonStoltz is the correct one:

1) Apache Commons HTTPClient project has a "DateUtil" class that I was hoping would work. http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/util/DateUtil.html. This provides convenience methods to format the date into a few standard formats to communicate dates in http headers... however, none of them seemed to match exactly what was being returned by the servlet container.

Use a DateTime library to get a date object for one hour in the future (or whatever time), and then use the Apache DateUtil class. That class outputs according to the RFC, so you do not have to worry that it does not match what your servlet 'usually produces' - browsers will respect the RFC!

Your code will look something like this:

// for one hour later (should probably use date libraries in general, this is somewhat awkward)
Date expiresDate = new Date(new Date().getTime() + 3600*1000); 
response.setHeader("Set-Cookie", "Expires=" + DateUtil.formatDate(expiresDate) + ";");


来源:https://stackoverflow.com/questions/4620172/expires-string-in-cookie-header

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!