【问题标题】:Server-Side Redirect in PHPPHP 中的服务器端重定向
【发布时间】:2009-12-30 22:50:03
【问题描述】:

我有一个 Java 应用程序,我需要将我们现有的 PHP 网站与之集成。供应商希望我们进行服务器端重定向以允许安全身份验证和单点登录,但我不确定如何在 PHP 中执行此操作。供应商解释了工作流程如下:

  1. 用户点击我们 PHP 网站上的“打开应用程序”链接
  2. PHP 应用程序在 Java 应用程序上点击一个页面,发送身份验证参数
  3. 如果成功,PHP 应用程序会将标头发送回用户的浏览器,这会强制“重定向”,否则 PHP 应用程序会显示错误

这将允许我们的 PHP 应用程序安全地与 Java 应用程序通信,并且客户端永远不必发送任何类型的身份验证。

据我了解,.NET 和 Java 内置了此功能,但我在 PHP 中找不到执行此操作的方法。有任何想法吗?

更新

我不是在谈论使用 header("Location: ...");执行重定向的功能。这种服务器端重定向的关键在于应用程序进行身份验证并将所有信息发送回客户端,以便客户端随后登录。使用 header("Location: ...") 只会强制浏览器运行其他地方。

更新 2

autologin.php(模拟用户通过 curl 登录外部应用)

// The login 'form' is at login.php
$ch = curl_init('http://domain.local/login.php');
// We are posting 2 variables, and returning the transfer just so it doesn't dump out
// Headers are processed by the callback function processHeaders()
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'processHeaders');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'username=user&password=pass');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Execute curl, close the connection, and redirect the user to a 'restricted' page
$response   = curl_exec($ch);
curl_close($ch);
header("Location: http://domain.local/restricted.php");

function processHeaders($ch, $header) {
    // Dump the response headers to the client
    header($header);
    strlen($header);
}

login.php(包含“登录”表单)

session_start();
if($_POST) {
    if($_POST['username'] == 'user' && $_POST['password'] == 'pass') {
        $_SESSION['auth'] = 1;
        $_SESSION['token'] = md5(time());
    } else {
        echo 'Auth failed';
    }
} else {
    echo 'Invalid access type';
}

restricted.php(受限页面)

session_start();
if($_SESSION['auth']) {
    echo 'Secret Token: '.$_SESSION['token'];
} else {
    echo 'Please log in';
}

这个想法是用户希望最终访问“restricted.php”。 “login.php”包含登录所需的代码。我要模拟的是用户在“login.php”上填写表单并将用户登录到“restricted.php”。

上面的 sn-ps 代码在我的本地测试中协同工作(点击 autologin.php 重定向到 restricted.php 并打印出秘密令牌),但我似乎无法让它跨应用程序工作。这些应用程序将位于同一域中(https://domain.com/myapphttps://domain.com:1234/vendorapp)。

我以前从来没有用任何语言做过这件事,我只是偏离了我的供应商告诉我他们已经做过的事情。显然,他们以前从未处理过 PHP,也不知道该怎么做。

【问题讨论】:

  • 重新更新:我不明白。您的意思是 PHP 应用程序将收到的标头从 Java 应用程序“转发”到浏览器吗?然后将适用相同的原则,您可以使用header 设置标题以及正文中所需的任何其他格式的任何其他信息。
  • 他说的不是简单的服务器端POST吗?阅读问题的#2。
  • @deceze 那么使用带有 CURLOPT_HEADER => true 的 cURL 并将标头信息转储给用户工作吗?
  • 使用不同的协议(http vs https)和不同的端口违反了跨域策略。
  • @Chris T 真该死。这可能就是为什么它在我的本地机器上运行良好,而不是当我在现实世界中尝试它时。有时,我讨厌安全:P

标签: java .net php server-side


【解决方案1】:

像这样:

header("Location: http://www.example.com/")

但它必须在任何其他代码之前...参见 php.net

【讨论】:

    【解决方案2】:

    你只需像这样输出一个普通的 HTTP 重定向 header()

    <?php header('Location: http://www.example.com/'); ?>
    

    重新更新

    如果我理解正确,您需要这样做:

    1. 浏览器向 PHP 服务器发送登录请求
    2. PHP 脚本以某种特定形式为 JSP 应用程序打包登录信息
    3. PHP 脚本 POST(通过 cURL)或 SOAPs 或 JSP 应用所需的任何内容
    4. PHP 接收响应并解析出必要的信息
    5. PHP 将标头和/或正文数据发送回浏览器

    第 4 步(解析信息)取决于您发送和接收信息的方式。如果您通过 cURL 在标头中收到它们,则需要将 set CURLOPT_HEADERtrue 并从响应中解析出必要的数据。这可能就像在第一个空行上拆分字符串一样简单,也可能更复杂,这取决于您的具体情况。

    您如何在您的应用中登录用户也是您需要处理的事情。 JSP 应用程序可能会处理实际的密码和用户名,并将您需要跟踪的某种令牌交还给您。

    【讨论】:

    • 用户已经通过身份验证进入我的应用程序。供应商说没有交换令牌(我们有另一个第三方服务可以做到这一点,我们发布一个秘密的用户名/密码并取回一个临时登录令牌),我们只是针对他们发布并将标头推回客户端浏览器。
    • 那么我希望这里的答案能给你足够的帮助来完成这项工作,否则你将不得不更详细地解释你想知道的究竟是什么。 :)
    • 也许告诉我们您在 .NET 和 Java 中究竟会做什么会有所帮助,这样我们就可以告诉您 PHP 的等价物。
    【解决方案3】:

    听起来您正在寻找通常与 PHP 捆绑在一起的 curl 库。

    http://php.net/manual/en/book.curl.php

    <?php
    session_start();
    
    // Receive username / password from $_POST
    
    // Prepare CURL object for post
    
    // Post u/p to java server
    
    // Read response
    
    if($success)
    {
        header('Location: nextpage.php');
        $_SESSION['LoggedInTime'] = time();
        exit;
    } 
    else
    {
        //display error
    }
    

    更新:

    稍后,您可以检查$_SESSION['LoggedInTime'] + 3600 &gt; time() 以查看他们是否仍然登录。每次他们访问已登录的页面时,请执行以下操作:

    if($_SESSION['LoggedInTime'] + 3600 > time()) 
    {
         $_SESSION['LoggedInTime'] = time() + 3600;
    } 
    else
    {
         header('Location: /login.php?Message=session+expired');
         exit;
    }
    

    希望这会有所帮助。

    【讨论】:

    • 如何让客户端“登录”?这不只是使用 curl 而不是用户本身登录我的应用程序吗?
    【解决方案4】:

    如果您正在尝试在 Web 上集成 php 和 java,您可能需要查看 Quercus/Resin。然后您的 PHP 可以直接调用 java 代码。由于它们在同一台服务器上运行,Java 代码可以编写任何 cookie、设置任何会话或进行任何必要的设置处理。 http://www.caucho.com/resin-3.0/quercus/tutorial/module/index.xtp

    【讨论】:

    • 不幸的是他们不会在同一个盒子里,但这仍然很有趣
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多