最佳安全实践是不要依赖浏览器中发生的任何事情。
这意味着您应该始终弄清楚服务器上的权限(在 PHP 端)。
变体 1(简单)
假设您已经对用户进行了身份验证,并且在 PHP 中用户为 $currentUser,其 ID 为 $currentUser->id。
现在这个用户想通过请求 url "profile?id=555" 来查看一些个人资料
这就是(基本上)你在 PHP 方面所做的事情:
$requestedProfile = (int)$_GET['profile'];
if ($requestedProfile == $currentUser->id) {
// they want own profile
show_controls_for_own_profile();
} else {
// they want someone else's profile
show_controls_for_other_profile();
}
在这种情况下,jQuery 与这里无关。
变体 2(单独的请求)
此外,假设您要缓存整个个人资料页面以将其快速加载到浏览器中,然后才通过 ajax-load 加载与用户权限相关的其他控件。
那么你有两个控制器方法(php 脚本,等等),每个都服务于它自己的部分:
public function showProfile() {
$requestedProfile = (int)$_GET['profile'];
if (profile_exists($requestedProfile)) {
show_the_profile($requestedProfile); // no check here
}
}
上述方法将通过其 ID(带有空的“.controls”元素)返回通用配置文件页面,并且在该页面上,一些 jquery 代码会要求服务器返回适当的用户变体 -依赖部分。
$.ajax('/user-controls.php')
.done(function(response) { $('.controls').html(response); });
请注意,它不会告诉服务器任何用户 ID - 服务器应该已经知道会话中当前经过身份验证的用户 ID!
第二个函数,和开头一样,将只返回控件的 HTML:
// Example of getting current profile from server's headers
function get_viewed_profile_id()
{
// url of previous profile page, e.g. http://example.com/profile?id=555
$referer = $_SERVER['HTTP_REFERER'];
$query = parse_url($referer, PHP_URL_QUERY); // id=555
parse_str($query, $params); // ['id' => '555']
return $params['id']; // 555
}
// we should store the authenticated user in session,
// not rely on anything user sends from their browser
$currentUserId = $_SESSION['user']->id;
$requestedProfileId = get_viewed_profile_id();
// now that we know both viewed profile and current user,
// we can compare them
if ($requestedProfileId == $currentUserId) {
// they want own profile
show_controls_for_own_profile();
} else {
// they want someone else's profile
show_controls_for_other_profile();
}
变体 3(将 PHP 变量传递给 javascript)
同上,但你不依赖$_SERVER['HTTP_REFERER'],而是将一些逻辑转移到Javascript:
浏览器询问:
// look up currently browsed profile from current window url
var q = new URLSearchParams(window.location.search);
var controlsURL = '/user-controls.php?viewedProfile=' + q.get('id');
// ask for controls, specifying the currently browsed profile
$.ajax(controlsURL)
.done(function(response) { $('.controls').html(response); });
服务器响应:
function get_viewed_profile_id()
{
return (int)$_GET['viewedProfile'];
}
// we should store the authenticated user in session,
// not rely on anyhting user sends from their browser
$currentUserId = $_SESSION['user']->id;
$requestedProfileId = get_viewed_profile_id();
// now that we know both viewed profile and current user,
// we can compare them
if ($requestedProfileId == $currentUserId) {
// they want own profile
show_controls_for_own_profile();
} else {
// they want someone else's profile
show_controls_for_other_profile();
}