php参数特殊字符,PHP中URL中特殊字符引起的问题(+,=) 分析及解决方法

前言,在做一个登录的过程中,发现个别账号验证通不过,仔细排查后发现是接收的参数进行了urldecode处理,使得某些特殊字符如加号’+‘变成了空格,以至于影响到了后面的数据。下面来看看代码。

get 方法代码

function get($key = null, $default = null) {

if (is_null($key)) {

foreach ($_GET as $key => $val) {

$_GET[$key] = trim(urldecode($val));

}

return $_GET;

} else {

$_GET[$key] = (isset($_GET[$key]) && $_GET[$key] != '') ? $_GET[$key] : $default;

return trim(urldecode($_GET[$key]));

}

}

登录验证代码

$input = \Util::get('data');

$data = json_decode(base64_decode($input), TRUE);

if ($this->do_verify($data) != 1){

$output['msg'] = "登陆验证失败!";

return (json_encode($output));

}

上述代码\Util::get(‘data’)接收到的 data 数据:

eyJ1aWQiOiIxMTc5NTIwNDA1MDAwNDI1IiwidWluIjoiQe 8h 8hyDkuIDliIDYgiIsInRva2VuIjoiQDE3MUA5MUAxNjNAODJAMTExQDg4QDExMEAxMDNAMTA1QDE1NkAxMDRAMTEwQDEwNkAxMDhAMTUyQDE0OUA4NkA5NkA4N0AxNzJAMTU5QDE0OUA5MEAxMTRAODNAMTAyQDEwM0AxMDhAMTExQDEwNEAxMDVAMTAzQDEwMEAxMDVAMTAxQDk2QDEwMUAxMDJAMTA3QDEwNEAxMDJAODlAOTdAOTFAMTY5QDE1NkAxNjFAMTUyQDg2QDExMEAxMDRAMTAzQDEwM0A5M0A5MEAxNTVAODNAMTExQDg4QDEwM0AxMDZAODVAMTgwIn0=

可以看到有两处分别有一个空格和两个空格,通过base64_decode和json_decode后,值成了 NULL,因此通不过后面的验证。

要怎么办呢,$data 这里肯定是不能改的,不然会影响绝大部分的登录,通不过验证的毕竟只是小部分,最好的方法就是在 if 里将获取的数据进一步处理,将特殊字符解析出来,既然接收的时候用了urldecode,那就将它用urlencode转回来吧

$input = urlencode($input);

urlencode转换后的数据:

eyJ1aWQiOiIxMTc5NTIwNDA1MDAwNDI1IiwidWluIjoiQe+8h++8hyDkuIDliIDYgiIsInRva2VuIjoiQDE3MUA5MUAxNjNAODJAMTExQDg4QDExMEAxMDNAMTA1QDE1NkAxMDRAMTEwQDEwNkAxMDhAMTUyQDE0OUA4NkA5NkA4N0AxNzJAMTU5QDE0OUA5MEAxMTRAODNAMTAyQDEwM0AxMDhAMTExQDEwNEAxMDVAMTAzQDEwMEAxMDVAMTAxQDk2QDEwMUAxMDJAMTA3QDEwNEAxMDJAODlAOTdAOTFAMTY5QDE1NkAxNjFAMTUyQDg2QDExMEAxMDRAMTAzQDEwM0A5M0A5MEAxNTVAODNAMTExQDg4QDEwM0AxMDZAODVAMTgwIn0%3D

仔细看,加号’+‘出来了

再用json_decode(base64_decode($input)), TRUE)处理$input 后发现还是 NULL,为什么呢,一步步分析,先查看base64_decode($input)是什么

{"uid":"1179520405000425","uin":"A'' 一刀؂","token":"@171@91@163@82@111@88@110@103@105@156@104@110@106@108@152@149@86@96@87@172@159@149@90@114@83@102@103@108@111@104@105@103@100@105@101@96@101@102@107@104@102@89@97@91@169@156@161@152@86@110@104@103@103@93@90@155@83@111@88@103@106@85@180"}7

这个 json 数据后面怎么会单独有个数字呀,一看就不对,怪不得 json_decode 后数据是 NULL,那这个 7 是如何来的呢,数据先是urlencode后再base64_decode,这里可以发现,urlencode后,使得原数据’=‘号变成了’%3D‘,进而造成base64_decode解析错误,所以使用urlencode还是不太正确的,那么究竟用什么来解决这一问题。

这就要讲到rawurldecode了,先来看下它的含义,

(PHP 4, PHP 5, PHP 7)

rawurldecode — 对已编码的 URL 字符串进行解码

说明

rawurldecode ( string $str ) : string

返回字符串,此字符串中百分号(%)后跟两位十六进制数的序列都将被替换成原义字符。

那么就来用下 rawurldecode 吧

$input = rawurldecode(urlencode($input));

再次查看$input 的值:

eyJ1aWQiOiIxMTc5NTIwNDA1MDAwNDI1IiwidWluIjoiQe+8h++8hyDkuIDliIDYgiIsInRva2VuIjoiQDE3MUA5MUAxNjNAODJAMTExQDg4QDExMEAxMDNAMTA1QDE1NkAxMDRAMTEwQDEwNkAxMDhAMTUyQDE0OUA4NkA5NkA4N0AxNzJAMTU5QDE0OUA5MEAxMTRAODNAMTAyQDEwM0AxMDhAMTExQDEwNEAxMDVAMTAzQDEwMEAxMDVAMTAxQDk2QDEwMUAxMDJAMTA3QDEwNEAxMDJAODlAOTdAOTFAMTY5QDE1NkAxNjFAMTUyQDg2QDExMEAxMDRAMTAzQDEwM0A5M0A5MEAxNTVAODNAMTExQDg4QDEwM0AxMDZAODVAMTgwIn0=

真相呼之欲出了,这里已经得到了正确的原数据,那么只要进一步优化验证逻辑,含有特殊字符的登录就走得通了,代码如下

$input = \Util::get('data');

$data = json_decode(base64_decode($input), TRUE);

if ($this->do_verify($data) != 1){

//得到正确的登录数据

$input = rawurldecode(urlencode(urldecode($input)));

//将正确的登录数据再进行一次验证

$data = json_decode(base64_decode($input),TRUE);

if ($this->do_verify($data) != 1) {

$output = "登陆验证失败!";

return (json_encode($output));

}

}

至此,特殊字符造成的解析问题解决完毕。

【声明】:本博客仅为分享信息,不参与任何交易,也非中介,所有内容仅代表个人观点,均不作直接、间接、法定、约定的保证,读者购买风险自担。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。

【关于安全】:任何 IDC 都有倒闭和跑路的可能,备份永远是最佳选择,服务器也是机器,不勤备份是对自己极不负责的表现,请保持良好的备份习惯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值