简体   繁体   English

GAE - PHP会话不起作用

[英]GAE - PHP sessions not working

I have an web app hosted using Google App Engine, and it uses PHP sessions to check if the user is logged in, etc. 我有一个使用Google App Engine托管的网络应用程序,它使用PHP会话来检查用户是否已登录等。

session_start() is present in all scripts, through a config.php script that is included in all of them. session_start()存在于所有脚本中,通过所有脚本中包含的config.php脚本。 The application works with Iframes, and those receive a session_start() call as well. 该应用程序与Iframes一起使用,并且那些也接收session_start()调用。

Locally, it works very fine, but when deployed it acts like the $_SESSIONS variables are expiring short after the user logs in. For example, sometimes when the user submits the login form, the page is redirected to the login again (which is the behaviour expected for all pages, when the user is not logged in). 在本地,它工作得非常好,但是在部署时,它就像$ _SESSIONS变量在用户登录后过期一样。例如,有时当用户提交登录表单时,页面会再次重定向到登录(这是当用户未登录时,所有页面的预期行为)。 This is a random event, sometimes it works, sometimes it won't. 这是一个随机事件,有时它会起作用,有时它不会。

I tried changing the php.ini with session.cookie_lifetime=0 and putting session_start() in the topmost line of the script. 我尝试使用session.cookie_lifetime=0更改php.ini并将session_start()放在脚本的最顶行。

Here's the config.php script (which is included in all scripts): 这是config.php脚本(包含在所有脚本中):

<?php
session_start();

$cur_page = $_SERVER["SCRIPT_NAME"];
if ((!isset($_SESSION['userid']) || $_SESSION['userid']=='') && $cur_page != '/login.php' 
    && $cur_page != '/redef-senha.php' && $cur_page != '/nova-senha.php' ) {
    // página solicitada, caso seja diferente de scope_home, login, logout
    // para garatir sincronia dos Iframes
    $request = ( $_SERVER['REQUEST_URI'] != '/login.php' 
            && $_SERVER['REQUEST_URI'] != '/scope_home.php' 
            && $_SERVER['REQUEST_URI'] != '/logout.php'
            && $_SERVER['REQUEST_URI'] != '/') ? '?r='.$_SERVER['REQUEST_URI'] : '';

    header('Location: http://'. ROOT_HOST . '/login.php'.$request ); // não, redireciona
    die(); // pára execução do restante do script
}

And here's the login.php (as an example): 这是login.php(作为示例):

<?php
    // vincular arquivos de configurações e classes
    require_once($_SERVER['DOCUMENT_ROOT']. '/config.php');
    require_once($_SERVER['DOCUMENT_ROOT']. '/head.php');

    use orm\orm\TblUsuarioQuery As UsuarioQuery;
    use orm\orm\TblGrupoQuery As GrupoQuery;

    $redirect = isset( $_GET['r'] ) ? $_GET['r'] : '/scope_home.php';

    // Checar se o login está correto
    $errmsg = "Entre com seu usuário ou e-mail e senha:";
    if (isset($_POST['user']) && isset($_POST['pass'])) {

        $user = filter_var($_POST['user'], FILTER_SANITIZE_STRING);
        $pass = filter_var($_POST['pass'], FILTER_SANITIZE_STRING);

        $q = new UsuarioQuery();
        if ( strpos($user, '@') !== false ) {
            $usuario = $q->filterByEmail($user)->findOne();       
        } else {
            $usuario = $q->filterByLogin($user)->findOne();       
        }            

        if ( $usuario == null ) {
            $errmsg = "Usuário ou e-mail não existe. Verifique e tente novamente:";
        } else {
            $q = new GrupoQuery();
            $grupo = $q->filterByTblUsuario($usuario)->findOne();    

            if ( !password_verify($pass, $usuario->getSenha())) {
                    $errmsg = "Usuário ou senha incorretos. Verifique e tente novamente:";
            } else {
                /* inicia a sessão */
                $_SESSION['username'] = $usuario->getLogin();
                $_SESSION['userid'] = $usuario->getCodUsuario();    
                $_SESSION['empresa'] = $grupo->getCodEmpresa();
            }
        }
    }

    // Usuário logado?
    if (isset($_SESSION['userid'])) {
        // redireciona para o url solicitado
        header('Location: http://'. ROOT_HOST . $redirect); // sim, redireciona
    } 
?>

The default deployment uses multiple instances, and the sessions seem to be stored privately per instance. 默认部署使用多个实例,并且会话似乎每个实例都以私有方式存储。 If you reload the page a few times, you will see your session exists sometimes and not exist other times as you toggle between instances. 如果您重新加载页面几次,您将看到有时存在会话,而在实例之间切换时则不会存在。

In the standard environment, GAE seems to replace the session store with a shared storage facility; 在标准环境中,GAE似乎用共享存储设施替换会话存储; in the flexible environment it does not seem to do so. 在灵活的环境中,它似乎并没有这样做。

You should be able to configure PHP to use a memcache storage for sessions, but in flex you need to provide your own memcache server. 您应该能够将PHP配置为使用memcache存储进行会话,但在flex中,您需要提供自己的memcache服务器。 The docs point to using redislabs as a vendor that can provide a memcache running inside the same data centers as your GAE app. 文档指出使用redislabs作为供应商,可以提供与GAE应用程序在同一数据中心内运行的内存缓存。 In your php.ini add: 在你的php.ini中添加:

session.save_handler = memcached                                                               
session.save_path = "host:port"

where host:port is from the settings that redislabs gives you. 其中host:port来自redislabs为您提供的设置。 You can also use a redis instance instead of memcache, but I've not gotten that to work with a password. 您也可以使用redis实例而不是memcache,但我没有使用密码。 I also have not gotten memcached session to work with a password, either. 我也没有得到memcached会话来使用密码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM