我已经开始深入研究用户页面的干净 URL,我的大部分灵感来自 Stack Overflow 的做法。用户可以只输入他们希望查看的用户的用户 ID,然后将他们重定向到正确的 URL,包括显示名称。例如,如果我有 id 为 1 的帐户,则访问users/1
将重定向到users/1/JosephDuffy
,假设我的显示名称是JospehDuffy
。从这里,可以执行额外的操作,例如编辑自己,users/1/JosephDuffy/edit
编辑用户 1.users/1/username/edit
也会重定向到users/1/JosephDuffy/edit
. 上述所有示例都可以在完美的世界中运行,但很容易被破坏。
用户可以对其他人执行操作,例如users/2/Player2/befriend
. 显然,你不想和自己交朋友,所以users/1/JospehDuffy/befriend
什么也不做。但是,输入一个 URL,例如users/1/1/1/1/JosephDuffy/befriend
似乎触发了动作 as befriend
,显示名称 asJosephDuffy
和用户 id as 1/1/1/1
。我猜这就是 mod_rewrite 的工作原理,但它似乎给我扔了一些曲线球。
现在,我intval()
在用户 ID 上使用,这似乎有效但不太理想;我仍然有多个提供相同信息的 URL,虽然我找不到任何其他“漏洞”,但可能仍然存在一些。我不确定问题出在哪里,所以我将发布我的 .htaccess 和 PHP 脚本。
.htaccess
RewriteEngine On
# Rewrite /users to provide the script with the GET variables it requires to function properly, whilst having clean URLs
# 3 variables were provided
RewriteRule ^users/([^.]+)/([^.]+)/([^.]+)/$ users.php?userid=$1&displayname=$2&action=$3
RewriteRule ^users/([^.]+)/([^.]+)/([^.]+)$ users.php?userid=$1&displayname=$2&action=$3
# 2 variables were provided
RewriteRule ^users/([^.]+)/([^.]+)/$ users.php?userid=$1&displayname=$2
RewriteRule ^users/([^.]+)/([^.]+)$ users.php?userid=$1&displayname=$2
#1 variable was provided
RewriteRule ^users/([^.]+)/$ users.php?userid=$1
RewriteRule ^users/([^.]+)$ users.php?userid=$1
我认为如果我在这个阶段的某个阶段使用或类似的东西也会更好[R=301,L]
,但我不确定在哪里,或者为什么真的。
users.php(有些部分被简化了,几乎是伪代码,以便于理解)
if (isset($_GET['userid'])) {
$profileUserid = intval($_GET['userid']);
} else {
$profileUserid = 0;
}
if (isset($_GET['displayname'])){
$profileDisplayName = $_GET['displayname'];
} else {
$profileDisplayName = '';
}
if (isset($_GET['action'])) {
$action = $_GET['action'];
} else {
$action = false;
}
$actualDisplayName = GetDisplayNameFromDBWhereid($profileUserid);
if ($actualDisplayName != $profileDisplayName) {
header('Location: /users/' . $profileUserid . '/' . $actualDisplayName . '/' . $action);
exit;
} else if (substr($_SERVER['REQUEST_URI'], -1) != '/') {
// There is no trailing slash, so add it
header('Location: ' . $_SERVER['REQUEST_URI'] . '/');
exit;
}
if ($currentUsersid == $profileUserid) {
// Player is viewing themselves
if ($action == 'edit') {
echo 'Editing your profile';
} else {
// User viewing self, but not editing
echo '<a href="edit">Edit your profile</a><br>';
}
} else {
if ($action) {
// Interact with the user whos profile is being viewed
} else {
}
}
如果不使用intval($_GET['userid'])
,当我输入 时users/1/1/1/1/JosephDuffy/action
,它会action
像我在其他用户的位置一样执行,同时1/JosephDuffy/action
显示“编辑您的个人资料”链接,忽略该操作,因为它不等于“编辑”。
希望这是一件愚蠢的事情(我猜这是我写得不好的 RewriteRules 的错),但绝不是这样,谢谢你的阅读。