天天看點

php中cookie的值包含加号(+)擷取變成空格的問題分析

背景

最近發現有部分使用者回報,擷取不到登入資訊,于是進行分析

分析

我們的登入資訊是加密存儲到cookie中的,檢視了下這個使用者的 cookie加密資訊中包含  加号“+” ,但是 php $_COOKIE 擷取的時候,變成了空格,于是解密失敗

分析請求頭中的資訊發現,請求傳過來的值是有 “+” 的,但是 :

php中cookie的值包含加号(+)擷取變成空格的問題分析

比如cookie中存儲的  “cWEolyrQ0l63FG+YWHA”  ,$_COOKIE 擷取出來顯示的  “cWEolyrQ0l63FG YWHA”  ,多了一個空格

于是查找資料

找到如下介紹:

注釋:在發送 cookie 時,setcookie 的值會自動進行 URL 編碼。接收時會進行 URL 解碼。如果你不需要這樣,可以使用 ​​setrawcookie()​​ 代替。

注釋:setrawcookie() 與 ​​setcookie()​​ 幾乎完全相同,不同的是不會在發往客戶機時,對 cookie 值進行自動 URL 編碼。使用setrawcookie,不能使用這些字元内的值:(; \ t \ r \ n \ 013 \ 014)

看這個介紹,自己覺得取出來以後urldecode 一下就行了

urldecode($_COOKIE['user_id'])

實際是不行的,于是嘗試  urlencode ,發現竟然成功了,但是如果cookie中有其他特殊字元 比如 "/" ,又不行了

urlencode($_COOKIE['user_id'])

是以這種方案,不能解決問題

解決方案

我們上面分析請求頭中的cookie是完整的,是以我們可以嘗試從請求頭中擷取cookie

<?php

// getallheaders 是 apache支援的函數,nginx下需要自己定義
if (!function_exists('getallheaders')) {
    function getallheaders()
    {
        foreach ($_SERVER as $name => $value) {
            if (substr($name, 0, 5) == 'HTTP_') {
                $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
            }
        }
        return $headers;
    }
}

$cookieStr = getallheaders()['Cookie'];
$cookies = explode(';',$cookieStr);
foreach($cookies as $cookie)
{
    $cookieTmp = explode('=',$cookie);
    $_COOKIE[trim($cookieTmp[0])] = trim($cookieTmp[1]);
}      

其他解決辦法

  1. 對cookie的值進行base64_encode(),拿來使用的時候再base64_decode()