My application needs to store the users email address in a cookie so that I can pre-populate a login form (username == email address)
. I set the cookie value in JavaScript. If I read it from JavaScript, I get [email protected]
. If I look at it in the cookie viewer in Firefox I get [email protected]
.
When I try to read it on the server-side in Java however, I only get foo
.
Do I need to do some sort of encoding/decoding here? If so, how do I do it in a way that can be decoded by both JavaScript and Java?
Thanks in advance! -Michael
My application needs to store the users email address in a cookie so that I can pre-populate a login form (username == email address)
. I set the cookie value in JavaScript. If I read it from JavaScript, I get [email protected]
. If I look at it in the cookie viewer in Firefox I get [email protected]
.
When I try to read it on the server-side in Java however, I only get foo
.
Do I need to do some sort of encoding/decoding here? If so, how do I do it in a way that can be decoded by both JavaScript and Java?
Thanks in advance! -Michael
Share Improve this question edited Jul 17, 2012 at 16:53 Uchenna Nwanyanwu 3,2043 gold badges37 silver badges59 bronze badges asked Nov 7, 2008 at 2:02 bowmanmcbowmanmc 311 silver badge4 bronze badges4 Answers
Reset to default 4From the javax.servlet.http.Cookie doco for setValue(String):
Assigns a new value to a cookie after the cookie is created. If you use a binary value, you may want to use BASE64 encoding.
With Version 0 cookies, values should not contain white space, brackets, parentheses, equals signs, mas, double quotes, slashes, question marks, at signs, colons, and semicolons. Empty values may not behave the same way on all browsers.
I'm guessing you need to BASE64 encode it on the way in (via JavaScript) and on the way out (via Java)
You need to escape the value part of your cookie.
document.cookie = name + "=" +escape( value )
+ ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" )
+ ( ( path ) ? ";path=" + path : "" )
+ ( ( domain ) ? ";domain=" + domain : "" )
+ ( ( secure ) ? ";secure" : "" );
I have found two solutions to this. Here is the first one.
Add back in padding to Base64 encoded strings. Inspiration for this came from http://fi.am/entry/urlsafe-base64-encodingdecoding-in-two-lines/
In this solution, the JavaScript stays the same (base64 encode everything) and the server side looks like:
public class CookieDecoder {
private static final Log log = LogFactory.getLog(CookieDecoder.class);
/**
* @param cookieValue The value of the cookie to decode
* @return Returns the decoded string
*/
public String decode(String cookieValue) {
if (cookieValue == null || "".equals(cookieValue)) {
return null;
}
if (!cookieValue.endsWith("=")) {
cookieValue = padString(cookieValue);
}
if (log.isDebugEnabled()) {
log.debug("Decoding string: " + cookieValue);
}
Base64 base64 = new Base64();
byte[] encodedBytes = cookieValue.getBytes();
byte[] decodedBytes = base64.decode(encodedBytes);
String result = new String(decodedBytes);
if (log.isDebugEnabled()) {
log.debug("Decoded string to: " + result);
}
return result;
}
private String padString(String value) {
int mod = value.length() % 4;
if (mod <= 0) {
return value;
}
int numEqs = 4 - mod;
if (log.isDebugEnabled()) {
log.debug("Padding value with " + numEqs + " = signs");
}
for (int i = 0; i < numEqs; i++) {
value += "=";
}
return value;
}
}
On the JavaScript side, you just need to make sure you base64 encode the values:
var encodedValue = this.base64.encode(value);
document.cookie = name + "=" + encodedValue +
"; expires=" + this.expires.toGMTString() +
"; path=" + this.path;
The second solution is just to URLEncode the Base64 encoded string. I'm using mons codec to do the encoding here. Java Code:
public class CookieDecoder {
private static final Log log = LogFactory.getLog(CookieDecoder.class);
/**
* @param cookieValue The value of the cookie to decode
* @return Returns the decoded string
*/
public String decode(String cookieValue) {
if (cookieValue == null || "".equals(cookieValue)) {
return null;
}
if (log.isDebugEnabled()) {
log.debug("Decoding string: " + cookieValue);
}
URLCodec urlCodec = new URLCodec();
String b64Str;
try {
b64Str = urlCodec.decode(cookieValue);
}
catch (DecoderException e) {
log.error("Error decoding string: " + cookieValue);
return null;
}
Base64 base64 = new Base64();
byte[] encodedBytes = b64Str.getBytes();
byte[] decodedBytes = base64.decode(encodedBytes);
String result = new String(decodedBytes);
if (log.isDebugEnabled()) {
log.debug("Decoded string to: " + result);
}
return result;
}
}
But now I have to decode it on the JavaScript side as well... Encode:
var encodedValue = this.base64.encode(value);
document.cookie = name + "=" + escape(encodedValue) +
"; expires=" + this.expires.toGMTString() +
"; path=" + this.path;
Decode:
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') {
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) == 0) {
var encodedValue = c.substring(nameEQ.length,c.length);
return this.base64.decode(unescape(encodedValue));
}
}
return null;