【问题标题】:Accessing REMOTE_USER from PHP/CakePHP从 PHP/CakePHP 访问 REMOTE_USER
【发布时间】:2009-05-26 10:28:43
【问题描述】:

我正在开发一个 CakePHP 网站,我刚刚使用 .htaccess 文件为其启用了 VAS 身份验证:

AuthType VAS

AuthVasUseBasic On
AuthVasRemoteUserMap local

Require valid-user

我希望能够使用$_SERVER['REMOTE_USER'] 找出谁登录了,但我发现$_SERVER 结构中缺少密钥:只有$_SERVER['REDIRECT_REMOTE_USER']。实际上,整个结构中充满了带有REDIRECT_ 前缀的键:

echo var_dump($_SERVER);
array(52) {
["REDIRECT_REDIRECT_REDIRECT_SCRIPT_URL"]=>  string(37) "/cake_1_2/feedbacks/edit/6" 
["REDIRECT_REDIRECT_REDIRECT_SCRIPT_URI"]=>  string(55) "http://test/cake_1_2/feedbacks/edit/6"
["REDIRECT_REDIRECT_REDIRECT_STATUS"]=>  string(3) "200" 
["REDIRECT_REDIRECT_SCRIPT_URL"]=>  string(37) "/cake_1_2/feedbacks/edit/6" 
["REDIRECT_REDIRECT_SCRIPT_URI"]=>  string(55) "http://test/cake_1_2/feedbacks/edit/6" 
["REDIRECT_REDIRECT_STATUS"]=>  string(3) "200" 
["REDIRECT_SCRIPT_URL"]=>  string(37) "/cake_1_2/feedbacks/edit/6" 
["REDIRECT_SCRIPT_URI"]=>  string(55) "http://test/cake_1_2/feedbacks/edit/6" 
["REDIRECT_HANDLER"]=>  string(8) "php5-cgi"
["REDIRECT_STATUS"]=>  string(3) "200" 
["SCRIPT_URL"]=>  string(37) ...
["REDIRECT_REMOTE_USER"]=>  string(9) "andygeers"
... 
}

我不确定发生了什么!这是在 POST 请求中生成的第一件事,它不会对这个特定的请求进行重定向。

这与 CakePHP 有关,还是只是一般的 PHP 问题?有什么想法吗?我现在在互联网上找到了很多页面,表明 REDIRECT_REMOTE_USER 是正常/常见的查找此值的地方,但似乎没有人知道为什么!

【问题讨论】:

  • 因为它可能是相关的:我也在 .htaccess 文件中使用 mod_rewrite

标签: php authentication cakephp


【解决方案1】:

Apache 正在添加这些 REDIRECT_ 前缀,以便脚本可以更好地处理发生的事情。对于我的应用程序,我编写了一个函数来处理这个问题。在我的例子中,它是一个类的方法,但是你可以很容易地将它变成一个全局函数。

class MyClass {
    /** @var integer How deep the redirect layers of Apache go. -1 means not set. */
    private $redirectLevel = -1;

    /**
     * Get an environment variable with all the REDIRECT_ prefixes stripped off
     */
    private function getEnv($var)
    {
        // Find out how deep the redirect goes
        if ($this->redirectLevel == -1) {
            reset($_SERVER);
            $key = key($_SERVER);
            $this->redirectLevel = substr_count($key, 'REDIRECT_');
        }

        $result = '';
        $prefix = '';
        for ($i = 0; $i < $this->redirectLevel + 1; $i++) {
            if (isset($_SERVER[$prefix . $var])) {
                $result = $_SERVER[$prefix . $var];
            }
            $prefix .= 'REDIRECT_';
        }
        return $result;
    }
}

编辑: 上面的函数返回具有最多 REDIRECT_ 前缀的变量的内容,这通常是您想要的。如果 Apache 不会为变量添加前缀,那么这就是您所得到的。变量的内容可以根据前缀的数量而改变。毕竟,Apache 添加了前缀,所以它不会覆盖旧值。

例如,在我的站点上,我使用 mod_ssl 通过客户端 SSL 证书进行客户端身份验证。证书主题(包含用户的电子邮件地址)存储在 SSL_CLIENT_S_DN 变量中。使用 Apache 前缀,这将显示为:

$_SERVER['REDIRECT_REDIRECT_SSL_CLIENT_S_DN'] // string containing the subject
$_SERVER['REDIRECT_SSL_CLIENT_S_DN'] // exists, but empty
// $_SERVER['SSL_CLIENT_S_DN'] does not exist

我上面写的getEnv()函数会返回顶部的。

【讨论】:

  • 无论包含多少个REDIRECT_前缀,是否所有值都保证相同?
【解决方案2】:

这是一个通用的 PHP 东西。一些框架根据其路由策略在内部重定向页面。如果您在框架之外重定向,您将获得相同的结果。

直接访问框架外的页面将为您提供您最初期望的名称。 我确实注意到在 CodeIgniter 中你得到$_SERVER['REMOTE_USER'] 并且没有重定向。所以这取决于你使用的框架。

因此,如果您不确定是否发生重定向,最好同时检查两者。

我还注意到您正在使用AuthVasUseBasic On。如果您使用它,您还应该检查基本用户身份验证变量$_SERVER['USERNAME'] IIRC

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多