保护PHP Web服务(SOAP)

时间:2015-01-29 08:14:17

标签: php ajax web-services soap

我有一个PHP Web服务,它实际上可以帮助CMS对数据库进行一些更新。我一直在尝试在互联网上寻找解决方案,但还没有得到答案。

有没有办法检查向网络服务提出请求的用户是否有权这样做,即检查用户会话?

这是我的虚拟服务(services.php)

<?php
    function GetMyUserName($i)
    {
        return "admin101";
    }
     $server = new SoapServer(null,array('uri' => ROOT."includes/services.php"));
     $server->addFunction('GetMyUserName');
     $server->handle();
?>

这是用于使用服务的JavaScript(jQuery)[使用SOAP信封]

function GetMyUName() {
    var req1 = "";
    req1 += '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">\n';
    req1 += '<soap:Body xmlns:m="includes/services.php">\n';
    req1 += "<m:GetMyUserName>\n";
    req1 += "</m:GetMyUserName>\n";
    req1 += "</soap:Body>\n";
    req1 += "</soap:Envelope>";

    $.ajax({
        url: "includes/services.php",
        type: "POST",
        data: req1,
        cache: false
    }).done(function (data) {
        $("#UsernameTb").html($(data).find("return").text());
    });
}

是否有任何类似我们在ASP的WCF中允许在Web服务中使用Sessions的内容。

如果此信息有所帮助,我正在使用UserCake进行身份验证。

1 个答案:

答案 0 :(得分:3)

概述

坦率地说,UserCake看起来就像十年前写的那样。只需查看UserCake中的login.php,就会调用die()使用header("Location: account.php")来重定向客户端和echo的HTML。

这些都不适合服务范式。最重要的是,UserCake对重定向的依赖将使得几乎不可能在没有实质性修改的情况下利用SOAP或REST接口。只需查看securePage函数...

即可
//Check if a user has access to a page
function securePage($uri){
    // earlier code omitted for readability here...

    elseif(!isUserLoggedIn()) 
    {
        header("Location: login.php");
        return false;
    }

    // ...
}

服务通常不会重定向。它们返回格式化的响应有效负载(例如JSON或XML),并可以使用HTTP代码来指示服务查询的结果。有像OAuth这样的例外,但这与手头的问题完全无关。

如果你想要一些简单的东西,我建议你选择一个合适的框架,Code Igniter Symfony如果你想要一些健壮的东西。两者都完全能够支持纯HTML页面,API请求和身份验证/授权。但如果必须是UserCake ......

击败UserCake进入提交

快速搜索告诉我们Javascript must follow the redirect。客户端需要确定响应是HTML还是JSON,然后相应地处理。从this回答和this one解除的代码说明了如何使用jQuery完成此操作。

$.ajax({
  type: "POST",
  url: "services.php", 
  data: {action: 'someSecuredAction', data: 'some data for the command'}, 
  success: function(response, status, xhr){ 
    var ct = xhr.getResponseHeader("content-type") || "";
    if (ct.indexOf('html') > -1) {
     // If data looks like HTML, this is some page from UserCake
     // likely served by a redirect, just display it
     var newDoc = document.open("text/html", "replace");
     newDoc.write(response);
     newDoc.close();
    }
    if (ct.indexOf('json') > -1) {
     // If data looks like JSON we have a
     // successful 'service' response from the server
    } 
  }
});

理论上,浏览器会随请求传递任何相关的cookie,因此会话应该在服务器上可用。请随意纠正我,但通过阅读它听起来像会话cookie将通过AJAX请求传递。

然后您的示例'service'(services.php)文件可能会变成这样(switch只是一些人为的想法,让您了解如何从请求中访问数据)

// If this ends up redirecting,
// the client should just pass it on through
securePage($_SERVER['PHP_SELF']);

switch($_POST['action']) {
   case 'someSecuredAction':
       // Again, if this redirects the client should be able to cope...
       $loggedInUser->checkPermission(['someSecuredAction']);

       // Do secured stuff here
       $aResponse = someSecureAction($_POST['data']);

   break;
}

// Now be nice enough to return the response as JSON
// like we might expect from an actual service
header('Content-Type: application/json;');
echo json_encode($aResponse);