You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP隐藏或加密URL中携带的user_id参数

PHP参数user_id安全处理方案

原代码基础问题修正

你给出的示例代码存在两处基础问题:

  • href属性中id后缺少等于号,会导致参数无法正常识别,正确基础写法应为edit.php?id=<?php echo htmlspecialchars($row['user_id']); ?>
  • 输出到HTML的变量未做转义,存在XSS注入风险,建议统一用htmlspecialchars()包裹输出内容

方案1:隐藏URL中的user_id参数

如果不想让user_id出现在地址栏,可选择以下两种实现:

  • 会话存储(最优,适用用户仅能编辑自身数据的场景)
    直接将当前登录用户的user_id存在服务端$_SESSION中,编辑接口直接从会话中读取用户ID,完全不需要前端传参,从根源避免参数泄露、篡改风险。
  • 改用POST请求提交
    把a标签跳转换成form表单POST提交,将user_id放在隐藏域中,参数不会出现在URL中,也不会被浏览器历史、访问日志默认记录:
<form action="edit.php" method="post">
  <input type="hidden" name="user_id" value="<?php echo htmlspecialchars($row['user_id']); ?>">
  <button type="submit">Edit</button>
</form>

注意:POST请求仅能避免参数在URL暴露,并非绝对安全,后端仍需做校验


方案2:参数加密/签名(必须使用GET传参时的安全方案)

如果业务要求必须用GET跳转传参,可以通过加密或者签名的方式避免参数被篡改、遍历:

  • 对称加密user_id
    用服务端存储的密钥将user_id加密为乱码字符串后再放到URL中,后端收到参数后解密使用,第三方无法直接读取/篡改参数内容:
// 生成链接侧的加密逻辑
$secret_key = '你自己定义的服务端专属加密密钥,不可泄露';
$cipher = 'aes-128-cbc';
$iv = random_bytes(openssl_cipher_iv_length($cipher));
$encrypted_id = openssl_encrypt($row['user_id'], $cipher, $secret_key, 0, $iv);
// 拼接iv和加密结果后base64编码,避免特殊字符影响URL
$safe_param = base64_encode($iv . $encrypted_id);
// 输出链接
echo '<a href="edit.php?id=' . htmlspecialchars($safe_param) . '"><button>Edit</button></a>';

// edit.php侧的解密逻辑
$secret_key = '你自己定义的服务端专属加密密钥,不可泄露';
$cipher = 'aes-128-cbc';
$raw_param = base64_decode($_GET['id']);
$iv_len = openssl_cipher_iv_length($cipher);
$iv = substr($raw_param, 0, $iv_len);
$encrypted_id = substr($raw_param, $iv_len);
$user_id = openssl_decrypt($encrypted_id, $cipher, $secret_key, 0, $iv);
// 校验解密结果是否为合法数字后再使用
  • 参数签名校验
    若不需要隐藏user_id的值,仅要防止用户篡改参数遍历其他用户数据,可以给参数加签名校验:
// 生成链接侧的签名逻辑
$salt = '你自己定义的服务端专属盐值,不可泄露';
$user_id = $row['user_id'];
$sign = md5($user_id . $salt);
// 输出链接,同时传id和签名
echo '<a href="edit.php?id=' . htmlspecialchars($user_id) . '&sign=' . htmlspecialchars($sign) . '"><button>Edit</button></a>';

// edit.php侧的校验逻辑
$salt = '你自己定义的服务端专属盐值,不可泄露';
$input_id = $_GET['id'];
$input_sign = $_GET['sign'];
if (md5($input_id . $salt) !== $input_sign) {
  die('参数非法,请求已拒绝');
}

强制注意事项

无论使用以上任何一种方案,后端都必须加权限校验:确认当前登录的用户,确实拥有编辑传入的user_id对应内容的权限,这是防止越权操作的最后一道防线,不可省略。


内容的提问来源于stack exchange,提问作者Edo Tensei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:30:01