【问题标题】:GAE - PHP sessions not workingGAE - PHP 会话不起作用
【发布时间】:2017-07-17 17:28:57
【问题描述】:

我有一个使用 Google App Engine 托管的网络应用,它使用 PHP 会话来检查用户是否已登录等。

session_start() 存在于所有脚本中,通过包含在所有脚本中的 config.php 脚本。该应用程序与 iframe 一起使用,并且这些 iframe 也会收到 session_start() 调用。

在本地,它工作得很好,但在部署时,它的行为就像 $_SESSIONS 变量在用户登录后不久就会过期。例如,有时当用户提交登录表单时,页面会再次重定向到登录(这是用户未登录时所有页面的预期行为)。这是一个随机事件,有时有效,有时无效。

我尝试使用 session.cookie_lifetime=0 更改 php.ini 并将 session_start() 放在脚本的最上面一行。

这是 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
}

这里是 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
    } 
?>

【问题讨论】:

    标签: php google-app-engine session app-engine-flexible


    【解决方案1】:

    默认部署使用多个实例,会话似乎是每个实例私有存储的。如果您重新加载页面几次,当您在实例之间切换时,您会看到您的会话有时存在而其他时候不存在。

    在标准环境中,GAE 似乎将会话存储替换为共享存储设施;在灵活的环境中它似乎没有这样做。

    您应该能够将 PHP 配置为使用 memcache 存储会话,但在 flex 中您需要提供自己的 memcache 服务器。文档指出使用 redislabs 作为供应商,可以提供在与您的 GAE 应用程序相同的数据中心内运行的 memcache。在你的 php.ini 添加:

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

    host:port 来自 redislabs 为您提供的设置。您也可以使用 redis 实例而不是 memcache,但我还没有使用密码。我也没有让 memcached 会话使用密码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-15
      • 2014-07-09
      • 1970-01-01
      • 2013-02-09
      • 2014-02-08
      • 2020-05-26
      • 2013-11-10
      相关资源
      最近更新 更多