屏蔽URL参数


Masking URL parameters

我经常想重定向用户或通过电子邮件向他们发送链接,但我想屏蔽URL中的参数,这样他们就不会知道发送了什么额外信息。

例如,如果我想提供一个链接http://www.example.com/directory/但我也想为某人传递电子邮件地址和哈希的额外参数:

电子邮件:someone@example.com

哈希:22sd359d5823ddg4653dgfFSG2

我可以把它们发送到这个链接,但我不想让它们看到参数:

http://www.example.com/directory/someone%40example.com/22sd359d5823ddg4653dfgfFSG2

所以我的第一个想法只是base64_encode(),但随后你会在末尾得到那些愚蠢的==符号来表示额外的字节。而且base64编码也会生成相当长的字符串。

是否有一种更简单、URL友好的方式来编码字符串以隐藏其内容

你通常会怎么做?base64_encode()是标准做法吗

您可以生成一个short id并将它应该做的事情存储在数据库中。所以使用

http://www.example.com/directory/K2SP26 

例如,将个人的电子邮件地址与他们应该去的地方一起存储在数据库中。退房http://kevin.vanzonneveld.net/techblog/article/create_short_ids_with_php_like_youtube_or_tinyurl/

使用base64_encode()、gzcompress等对字符串进行编码并不是混淆字符串的好方法,因为解码它很简单。是的,另一种选择是将值存储在数据库中,然后按照人们的建议传递一个密钥。但假设你不想为此烦恼,你真正应该做的是使用私钥对其进行加密,然后在另一端使用相同的密钥对其进行解密。

例如:

function obfuscateString($s) 
{
    $secretHash = "BA2EC9E717B68176902FF355C23DB6D10D421F93EAF9EE8E74C374A7B0588461";
    return openssl_encrypt($s, 'AES-256-CBC', $secretHash, 0, '1234567890123456');
}
function unobfuscateString($s)
{
    $secretHash = "BA2EC9E717B68176902FF355C23DB6D10D421F93EAF9EE8E74C374A7B0588461";
    return openssl_decrypt($s, 'AES-256-CBC', $secretHash, 0, '1234567890123456');
}

(需要PHP版本>=5.3.0。)将$secretHash替换为您自己的secret十六进制字符串。

注意:在本例中,初始化向量(1234566789123456)只是一个填充字符串,但没关系。您可以想出一种使用唯一初始化向量的方法,但在大多数情况下,对于混淆URL参数而言,这并不重要。

这可能是一个愚蠢的答案,但为什么不使用mcrypt函数来向至少更普通的用户隐藏参数呢?

如果您的重定向是由PHP触发的,我想将数据存储在会话中是显而易见的选择。

<?php
function redirectTo($url, $data) {
    session_start();
    $hash = md5(uniqid("rediredt", true));
    $_SESSION[$hash] = array(
        'my' => 'data',
        'is' => 'invisible',
        'to' => 'the user',
    );
    $delim = strpos($url, '?') ? '&' : '?';
    $url .= $delim . 'redirection-key=' . $hash;
    // might want to send 301 / 302 header…
    header('Location: ' . $url);
    exit; // might want to avoid exit if you're running fcgid or similar
}
function isRedirected() {
    if (empty($_GET['redirection-key'])) {
        return null;
    }
    if (!isset($_SESSION[$_GET['redirection-key']])) {
        return array();
    }
    $t = $_SESSION[$_GET['redirection-key']];
    unset($_SESSION[$_GET['redirection-key']]);
    return $t;
}

可能会帮助您理解这个想法…

您有两个选择之一:

  1. 电子邮件地址经过散列处理,因此可以由精明的用户进行解码
    -或-
  2. 电子邮件地址存储在您的服务器(数据库)上,并且电子邮件链接仅包含数据库主ID

如果您想要最安全的方法,也能提供最漂亮的URL,请使用方法2。如果你绝对不想将电子邮件地址存储在数据库中,那么可以使用常见的哈希,如base64甚至rot13,也可以自己滚动。你会发现,滚动你自己的并不简单,但它会阻止大多数普通用户试图窥探哈希的内部。

这有点麻烦,但如果您向他们发送一个包含以下内容的页面:

<form id="getme" action="directory/someone" method="POST">
 <input type="hidden" name="email" value="someone@example.com">
</form>
<script> document.getElementById("getme").sumbit();</script>

一旦加载(假设它们启用了javascript),它们就会被重定向到您想要的位置,而不需要url目录。