1

我想知道如何最好地处理登录表单中的返回 url。我认为一个好方法可能是在这里完成。即对当前url进行urlencode,作为get参数发送给登录控制器。

然后可以在登录控制器中对其进行 urldecode。但那又如何呢?我查看了 StackOverflow 登录页面,但在任何地方都找不到该 URL。它存储在哪里?登录完成后它如何知道去哪里?它是否存储在 cookie 中?会话变量?或者是其他东西?

我想事情可以做的有点不同于PHP,但无论如何。有什么好方法可以做到这一点?

4

2 回答 2

1

如果是我,我会在会话中设置返回 URL。通过这种方式,您可以计算出适当的 URL 并将事物与表示层分开。在检测到设置了返回 URL 并且存在 post 对象时,您可以设置位置标头并退出脚本。例子...

// You have the URL to return to (could be a constantly updated session variable
// or simply set when a certain page is accessed via HTTP_REFERRER - it's open)
// in a MVC application (like stackoverflow) you could add this to the controller
// for any view with return functionality.
$_SESSION['RETURN_URL'] = $Url;

// Now you have validated and processed a form (from the model). If there is a 
// return url set, we redirect to it. Otherwise, we follow the default action of 
// the form
if ($FormValidatedAndSubmitted)
    returnToURL();

function returnToURL(){
    if (isset($_SESSION['RETURN_URL'])){
     header("Location: " . $_SESSION['RETURN_URL']);
     unset($_SESSION['RETURN_URL']);
     exit();
    }
}
于 2010-09-08T19:56:35.243 回答
0

如果它是静态 URL,那么您可以将其作为隐藏字段包含在表单中,然后在您的代码中重定向到它,即

<input type='hidden' name='return' value='/thankyou.html' />

然后在您的提交功能中...

header("Location: $_POST['return']");

在生产中,您显然希望对隐藏字段中的 URL 进行加密,然后在调用 header() 函数之前对其进行解密并验证它是一个好的 URL,但这应该会给您这个想法。

有些人使用 cookie,有些人在数据库中有一个查找表。将 URL 存储在哪里并不重要,重要的是在 header() 之前擦洗它。

编辑:擦洗

function isValidURL($url) {
   return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
}

if ( isValidURL($_POST['return']) )
    header("Location: {$_POST['return']}");

正如我之前所说,如果您想更加小心,您可以在显示在表单上和验证之前对实际 URL 进行加密/解密。那里有很多好的加密/解密库。

带回家的教训是永远不要对通过表单传入的数据实际“做任何事情”(例如在数据库中插入值、运行 shell 命令、重定向到 URL 等)。有人可以通过狡猾的方式操纵该隐藏字段并将代码注入您的应用程序或数据库。有数以千计的帖子展示了人们通过表单注入所做的事情。

于 2010-09-08T17:43:57.803 回答