Javascript请求交叉orgin PHP应用程序

时间:2017-04-18 18:30:53

标签: javascript php jquery request

我有一个PHP应用程序,我希望在我的前端部分运行XMLHttpRequests,这样可以正常工作,因为它与&#34;正常&#34; <相同/ em>的。这很好用。

当我开始尝试执行安全跨越原始请求时,我感到非常困惑。例如,我想在用户登录时只允许一些请求。但是,当测试会话是否仍在那里时,它不再存在。例如,我只是不希望随机人员访问某人的个人资料。或获取任何我不希望随机的人看到的数据。

我想要什么

通过以下所示的模型请求使其安全。因为我想要的一些数据仅用于保护登录用户。你是怎样做的?我无法解决这个问题。

enter image description here

基本上,我现在遇到的问题是,如果用户有活动会话,我无法在PHP端检查,因为PHP认为这是一个全新的事情。从本质上讲,你如何像网络broswers那样做呢?它可能只是非常愚蠢,但我无法绕过它。

我尝试了什么

我已尝试请求设置$_SESSION的位置,然后在返回$_SESSION的位置请求它,但它不会返回任何内容。这意味着我无法检查请求是否来自已登录的用户。

2 个答案:

答案 0 :(得分:1)

您可以使用JSON Web Tokens在各设备之间进行安全通信。

  

JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑且独立的方式,可以在各方之间作为JSON对象安全地传输信息。此信息可以通过数字签名进行验证和信任。 JWT可以使用秘密(使用HMAC算法)或使用RSA的公钥/私钥对进行签名。   Source

您基本上会将每个请求的令牌发送到您想要在登录后保护的来源。然后服务器端你非常喜欢那个令牌。登录后,您将生成该令牌并将其包含在您的回复中。在您的前端,您可以将令牌存储在客户端计算机上的本地存储中。例如jQuery has this plugin for local storage

以下是您需要在PHP中执行的操作的超级基本示例。

使用javascript / jQuery登录。例如,将用户名/密码发送到login.php,并像通常那样对用户进行身份验证。

的login.php

use \Firebase\JWT\JWT;

$salt = 'some_salt_string';
$algo = 'HS256'; // allowed ones

$params = array(
    "iss" => 'http://example.com', // your own identification
    "aud" => ['user_id'=>4324], // client identification
    "iat" => time(), // start validity
    "exp" => time()+(3600*24) // end validity
);

$token = JWT::encode($params, $salt, $algo);

// example data
$data = [
    'example_1'=>'value 1',
    'example_2'=>'value 2'
];
$response = array_merge($data,['token'=>$token]);

header('Content-Type: application/json');
echo json_encode($response);

auth.php

use \Firebase\JWT\JWT;

/**
 * http://stackoverflow.com/questions/40582161/how-to-properly-use-bearer-tokens
 * Get header Authorization
 * */
function getAuthorizationHeader(){
    $headers = null;
    if (isset($_SERVER['Authorization'])) {
        $headers = trim($_SERVER["Authorization"]);
    }
    else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
        $headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
    } elseif (function_exists('apache_request_headers')) {
        $requestHeaders = apache_request_headers();
        // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
        $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
        //print_r($requestHeaders);
        if (isset($requestHeaders['Authorization'])) {
            $headers = trim($requestHeaders['Authorization']);
        }
    }
    return $headers;
}
/**
 * http://stackoverflow.com/questions/40582161/how-to-properly-use-bearer-tokens
 * get access token from header
 * */
function getBearerToken() {
    $headers = $this->getAuthorizationHeader();
    // HEADER: Get the access token from the header
    if (!empty($headers)) {
        if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
            return $matches[1];
        }
    }
    return null;
}

$token = getBearerToken();
$salt = 'some_salt_string';
$algo = 'HS256';
$decoded_token = JWT::decode($token, $salt, $algo); // returns object

// you can access the audience properties to verify the user id against a requested resource
$user_id = $decoded_token->aud->user_id;

// finally check user id and either deny or allow access

的javascript

<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-storage-api/1.9.4/jquery.storageapi.min.js"></script>
<script>

    var storage=$.localStorage;

    function login() {

        $.ajax({
            url: 'https://example.com/api/login',
            type: 'POST',
            data: {
                username:'Username',
                password:'Password'
            },
            success: function (data) {
                storage.set('auth_token',data.token); // store returned token to local storage using the jQuery plugin"value"
            },
            error: function () {
                alert('Error occured');
            },
        });

    }
    function testApi() {

        $.ajax({
            url: 'https://example.com/api/test',
            type: 'GET',
            beforeSend: function (xhr) {
                xhr.setRequestHeader('Authorization', 'bearer '+storage.get('auth_token')); // append the token. Mind the space.
            },
            data: {
                query:'value'
            },
            success: function () {

            },
            error: function () { 

            },
        });
    }
</script>

在您的安全页面中包含auth代码段或更好地说明API端点。

答案 1 :(得分:0)

CORS或跨域请求是允许其他域访问您的Web服务。您要问的功能是用户级访问权限,或者我们可以说哪些是公开的,哪些仅限于用户角色。这与CORS无关。其次会话仅限于一个系统。请阅读w3schools的这一页,以便更好地理解会话https://www.w3schools.com/php/php_sessions.asp

您还可以在mysql或服务器端使用的任何数据库中维护用户级别变量,以了解用户级别,然后将其带到正确的会话中,并在每次请求时检查该类型的会话值像$ _SESSION [“user_type”]这样的用户可以从你的数据库中获取,然后在注销时销毁会话。