我正在尝试使用Silex创建一个REST API。它工作得很好,但现在我想使用会话变量来跟踪用户。我尝试使用常规的php会话变量和SessionServiceProvider。在我的一生中,会话变量不会在页面请求中持久化。查看我的临时会话文件夹,似乎每个请求都会创建一个新会话。
所以我在索引中包含许多 php 文件.php初始化$app的文件?我不确定这是否与它有关,但它可能与以下代码正在做什么有关。
索引.php
<?php
require_once 'vendor/autoload.php';
$config['displayErrorDetails'] = true;
$app = new Silex'Application();
$app->register(new Silex'Provider'SessionServiceProvider, array('session.storage.save_path' => dirname(__DIR__) . '/tmp'));
$app->before(function() use ($app){
$app['session']->start();
});
require "../apiSource/classes/employees.php";
$app->run();
员工.php
<?php
use Symfony'Component'HttpFoundation'JsonResponse as JsonResponse;
use Symfony'Component'HttpFoundation'Request as Request;
class Employees
{
private $database;
function __construct()
{
$this->database = getDB();
}
function loginEmployee($loginInfo, $app){
//.... check loginInfo with database of employee ....///
if ($isEmployee) {
$app['session']->set('userID', $employee['e_ID']);
return array('success' => 'success', 'e_ID' => $employee['e_ID'], 'session' => $app['session']->get('userID'));
//SUCCESS
} else {
return array('message' => 'Error.');
}
}
function isLoggedIn($app){
$stmt = $this->database->prepare("SELECT e_ID, e_Email FROM Employee WHERE e_ID = ?");
$stmt->execute(array($app['session']->get('userID')));
$employee = $stmt->fetch(PDO::FETCH_ASSOC);
if(empty($employee)){
return array('Error' => $employee, 'Session' => $app['session']->get('userID'));
}
return $employee;
}
function logout($app){
$app['session']->remove('userID');
return array('success' => 'success');
}
}
$app->get('/employees/logout', function() use ($app) {
$employees = new Employees();
$results = $employees->logout($app);
return new JsonResponse($results);
});
$app->get('/employees/status', function() use ($app) {
$employees = new Employees();
$results = $employees->isLoggedIn($app);
return new JsonResponse($results);
});
$app->post('/employees/login', function(Request $request) use ($app) {
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
$employee = new Employees();
$results = $employee->loginEmployee($data, $app);
return new JsonResponse($results);
});
当我的 Angular 应用程序发布对"{url}/employees/login"的调用时,会话变量被设置,它确实返回会话['userID']。但是,如果紧接着我调用"{url}/employees/status"以查看用户是否已登录,则会话变量为空。在保存会话变量的 tmp 文件夹中,我可以看到为每个请求创建一个新文件。
我做错了什么?任何帮助将不胜感激。
谢谢!
编辑
我试图在这里简化事情,看看发生了什么。它一定是我的角度页面发布,并病态地表明我的意思。
索引.php
$app->get('/hello', function () use ($app){
session_start();
$num = $_SESSION['idea'] ? $_SESSION['idea'] : 1;
$_SESSION['idea'] = $num+1;
echoResponse(200, $_SESSION['idea']);
});
如果我只是访问该页面并继续点击刷新,我的会话变量正在工作,并且它不断上升一个。因此,会话变量正在工作。
但是,当我尝试从我的角度应用程序调用此页面时:
$scope.hello = function(){
$http.get('https://viromo.com/cubex/api/hello').then(function(results){
console.log(results);
})
};
结果会不断回发相同的数字,而不会增加。不知道为什么会这样。我已经更新了标题和标签,以更好地反映我的问题目标。
谢谢!
就我而言,这是因为角度中缺少在请求标头中设置 cookie 的配置。
根据本文档:"默认情况下,在跨站点XMLHttpRequest或Fetch调用中,浏览器不会发送凭据。调用 XMLHttpRequest 对象或 Request 构造函数时,必须在它上设置特定的标志。
在角度中,它是通过添加配置行来完成的:
angular.module('app', ['your_dependencies...'])
.config(function ($httpProvider) {
// Enabling the use of cookies in angular
$httpProvider.defaults.withCredentials = true;
});
如果您使用 Apache 来托管后端,您可能需要编辑您的".htaccess",通过添加以下行来允许使用凭据:
# When using credentials flag, the wildcard '*' does not work, so you need to specify the site URL
Header always set Access-Control-Allow-Origin http://<your_site_url>
# Allowing credentials
Header always set Access-Control-Allow-Credentials true