我有一个PHP应用程序,我希望在我的前端部分运行XMLHttpRequests
,这样可以正常工作,因为它与&#34;正常&#34; <相同/ em>的。这很好用。
当我开始尝试执行安全跨越原始请求时,我感到非常困惑。例如,我想在用户登录时只允许一些请求。但是,当测试会话是否仍在那里时,它不再存在。例如,我只是不希望随机人员访问某人的个人资料。或获取任何我不希望随机的人看到的数据。
通过以下所示的模型请求但使其安全。因为我想要的一些数据仅用于保护登录用户。你是怎样做的?我无法解决这个问题。
基本上,我现在遇到的问题是,如果用户有活动会话,我无法在PHP端检查,因为PHP认为这是一个全新的事情。从本质上讲,你如何像网络broswers那样做呢?它可能只是非常愚蠢,但我无法绕过它。
我已尝试请求设置$_SESSION
的位置,然后在返回$_SESSION
的位置请求它,但它不会返回任何内容。这意味着我无法检查请求是否来自已登录的用户。
答案 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”]这样的用户可以从你的数据库中获取,然后在注销时销毁会话。