javascriptphpnode.jscookiespercent-encoding

Decoding raw URL-encoded cookie in JavaScript


I generate session cookies in PHP using

$cookie = random_bytes(64);

then set the value of this variable as a cookie:

setcookie('access', $cookie, time()+31536000, '/', false);

When I look for the desired value using

function getAccessToken(){
    var n = document.cookie.match(/access=([^;]+)(?:$|;)/i);
    if (n && n.length)
        return n[1];
}

on the client side, I get

"%1D%D8%E1%3F%7E%3E%D7b%A5%04%3Bl%3A%ADB%DF%DAg%E5%1DH%0A%21%5E%15%D9%2Be8k%3A%E2%AF%CE7%F2%BF%5B%CB%14%95%CEO%28%60p%DF%FBeY%95%3C%86%B99U%B7%F1p%E0%AC%2B%C5%2F"

This value is being sent to a Node.js websocket server to authenticate the user, but since the value is already wrong at the client side, the connection fails. When PHP receives this cookie, it is automatically decoded, and $_COOKIE['access'] correctly contains

��?~>�b�;l:�B��g�H
!^�+e8k:���7��[���O(`p��eY�<��9U��p��+�/

Everywhere I looked I was told to use decodeURI / decodeURIComponent and escape, but the first throws URIError: URI malformed and the second doesn't help me the slightest.

How can I turn this raw URL-encoded string into a string of actual characters/bytes on either the client OR Node.js (doesn't matter which side does the decoding)?


Solution

  • Based on @BlackBurn027's comment, all I did was add an extra bin2hex step before setting the cookie value:

    $cookie = bin2hex(random_bytes(64));
    

    This produces a string that both languages can easily understand without issues.