简体   繁体   中英

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.

session_start() is present in all scripts, through a config.php script that is included in all of them. The application works with Iframes, and those receive a session_start() call as well.

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). 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.

Here's the config.php script (which is included in all scripts):

<?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):

<?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; 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. The docs point to using redislabs as a vendor that can provide a memcache running inside the same data centers as your GAE app. In your php.ini add:

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

where host:port is from the settings that redislabs gives you. You can also use a redis instance instead of memcache, but I've not gotten that to work with a password. I also have not gotten memcached session to work with a password, either.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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