【问题标题】:Accessing session data outside Joomla在 Joomla 之外访问会话数据
【发布时间】:2010-11-13 14:52:38
【问题描述】:

我正在尝试在 Joomla 之外运行应用程序(而不是作为插件),并且我想访问已登录用户的信息(用户 ID)。我想知道我应该怎么做呢?有我可以包含的文件吗?我尝试使用 $_SESSION 但它显示为空。

我的问题有简单的解决方案吗?感谢您的宝贵时间。

【问题讨论】:

    标签: php joomla


    【解决方案1】:

    实际上,这并不像听起来那么容易。 Joomla 使用自己的会话处理,带有独特的会话 ID 生成和一些加密,因此进入 Joomla 会话数据的唯一方法是使用适当的 Joomla 功能(正如其他人所建议的那样)。我最近有一个项目,我们需要将经过 Joomla 身份验证的用户转移到单独的应用程序中。我们通过添加一个 Joomla 适配器来实现这一点,该适配器实例化 Joomla 用户类、读取用户数据、将所有内容放入加密的 cookie 并重定向回我们的应用程序。在那里,我们读取加密的 cookie,实例化我们自己的用户对象并丢弃 cookie。由于这不是 100% 安全的,我们正在更改系统以将用户数据写入数据库表并从我们的应用程序中读取 - 我们通过这种方式避免了通过 cookie 的不安全方式,因为即使 cookie 是加密的(并且包含足以验证用户身份的敏感用户信息)将通过网络传输并可能被嗅探。

    define( '_JEXEC', 1 );
    define('JPATH_BASE', dirname(dirname(__FILE__)));
    define( 'DS', DIRECTORY_SEPARATOR );
    
    require_once (JPATH_BASE . DS . 'includes' . DS . 'defines.php');
    require_once (JPATH_BASE . DS . 'includes' . DS . 'framework.php');
    
    $mainframe = JFactory::getApplication('site');
    

    以上是访问Joomla资源所需的基本脚本。

    【讨论】:

    • 我想将这种功能引入 CakePHP。基于蛋糕的站点托管在子域上。您认为您的建议适用于我的问题吗?
    • 我不知道 CakePHP 及其身份验证机制,但我认为这种方法通常可以工作 - 只要您能够将标识符(在我的情况下为 cookie)从应用程序 1 传输到应用程序2.给定一个子域,拥有一个可以从子域和主域读取的cookie应该没有问题。
    • 抱歉这个菜鸟问题,但我假设我们把它放在一个 PHP 脚本中,在基本的 Joomla 目录中?
    • @Jaryl:你必须把它放在 PHP 脚本中——这是正确的。这个脚本的位置无关紧要,只要将JPATH_BASE 常量调整为可以找到 Joomla 安装的路径即可。
    【解决方案2】:
     define( '_JEXEC', 1 );
    
     define('JPATH_BASE', 'your joomla basedir goes here' );
    
     define( 'DS', DIRECTORY_SEPARATOR );
     require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
     require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
    
     JDEBUG ? $_PROFILER->mark( 'afterLoad' ) : null;
     $mainframe =& JFactory::getApplication('site');
     $mainframe->initialise();
     JPluginHelper::importPlugin('system');
     JDEBUG ? $_PROFILER->mark('afterInitialise') : null;
     $mainframe->triggerEvent('onAfterInitialise');
    
     $user =& JFactory::getUser();
    
        if ($user->guest) {
            echo 'stuff';
                //redirect('/');
        } else {
            echo 'user';
        }
    

    【讨论】:

      【解决方案3】:

      解决方案是为您的整个域和/或站点设置会话。如果您尝试访问 joomla 范围之外的会话数据,它适用。例如,如果您的 joomla 站点位于 http://example.com/joomla/ 而您的其他站点位于 http://othersite.example.com/ 上,则保存会话 id 的 cookie 不会从 joomla 传输到其他站点。要修改此行为,请在每个 session_start() 之前使用 session_set_cookie_params (我不太了解 joomla,但您应该只添加几行代码)。以这种方式使用它:

      session_set_cookie_params(86400, '/', '.example.com');
      

      86400 是会话的生命周期,将其设置为您喜欢的值(86400 是一天)。 '/' 是 cookie 的路径。这意味着如果您的 joomla 站点位于 http://example.com/joomla/ ,如果用户访问 http://example.com/ ,会话 cookie 仍然会发送。

      '.example.com' 是域。注意开头的点,它非常重要。它表示会话 cookie 将在 example.com 的任何子域上发送。不放的话,cookie只会发送给http://example.com/开头的地址。

      这应该可以解决您的问题,除非您尝试从另一个域访问会话数据。如果是这样,请在这里发表评论,我会看看我是否能找到一些东西。

      【讨论】:

        【解决方案4】:

        Stefan Gehrig

        展示的解决方案
        define( '_JEXEC', 1 );
        define('JPATH_BASE', dirname(dirname(__FILE__)));
        define( 'DS', DIRECTORY_SEPARATOR );
        
        require_once (JPATH_BASE . DS . 'includes' . DS . 'defines.php');
        require_once (JPATH_BASE . DS . 'includes' . DS . 'framework.php');
        
        $mainframe = JFactory::getApplication('site');
        

        工作正常,我花了很多个漫长的夜晚尝试访问 Joomla! joomla 文件夹外的资源。

        $session     = &JFactory::getSession();
        

        在后续代码中,当 getApplication 方法被调用时可以正常工作。

        感谢您的解决方案。

        【讨论】:

          【解决方案5】:

          首先你必须为一些joomla的常量(标识符)提供如下定义:

          define( '_JEXEC', 1 );
          define( 'DS', DIRECTORY_SEPARATOR );
          define( 'JPATH_BASE',$_SERVER['DOCUMENT_ROOT'].DS. basename(dirname(__DIR__)) );
          

          其中:JPATH_BASE 代表您站点的根目录。一定是对的。

          在than之后,您必须使用以下密钥文件:

          require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
          require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
          

          之后,您必须创建一个应用程序对象并对其进行初始化:

          $mainframe =& JFactory::getApplication('site');
          $mainframe->initialise();  
          

          [这是可选的]如果你想导入一些其他的库,那么你可以这样做:

          jimport( 'joomla.user.user');
          jimport( 'joomla.session.session');
          jimport( 'joomla.user.authentication');
          

          所以你的文件的核心代码如下:

          define( '_JEXEC', 1 );
          define( 'DS', DIRECTORY_SEPARATOR );
          define( 'JPATH_BASE',$_SERVER['DOCUMENT_ROOT'].DS. basename(dirname(__DIR__)) );
          
          require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
          require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
          
          $mainframe =& JFactory::getApplication('site');
          $mainframe->initialise();
          
          //optional use depend on requirement 
          jimport( 'joomla.user.user');
          jimport( 'joomla.session.session');
          jimport( 'joomla.user.authentication');
          

          【讨论】:

            【解决方案6】:

            要获取用户 ID,您需要使用 Joomlas 函数:

            $user =& JFactory::getUser();
            $user->get('id');

            会让你得到用户ID。但是,您需要在 joomla 页面中执行此操作,所以我不知道这顶帽子对您有多大用处。

            【讨论】:

            • 这就是我所做的。我无法弄清楚我需要设置什么最小环境才能访问 Joomla 功能,所以我只是硬着头皮学习了如何编写组件。它们有点奇怪,但一旦你掌握了它,它们就不会那么糟糕了。那么至少,你几乎可以通过 Joomla API 获得任何你想要的东西。
            【解决方案7】:

            mod_login.php应用这个

            之后: $user =& JFactory::getUser();

            echo "<p>Your usertype is {$user->usertype} which has a group id of {$user->gid}.</p>";

            【讨论】:

              【解决方案8】:

              Joomla 很可能像 Wordpress 一样不使用任何“会话”数据,而是直接从数据库中提取数据。在这种情况下,您需要使用 Joomla 的原生函数。

              但这只是我使用 Wordpress 的经验。

              更新

              我想我错了。
              假设这是访问 Joomla Session 变量的 api 类:

              // 返回对全局的引用 JSession 对象,仅在以下情况下创建它 它尚不存在 $session = &JFactory::getSession();

              // 从会话变量中获取一个值 $value = $session->get('var_name', 空);

              // 将值放入会话 var $session->set('var_name', $value);

              【讨论】:

                【解决方案9】:

                了解在 jFusion 等应用程序桥中如何实现这一点可能会有所帮助。我建议至少为 Joomla 提供一个系统插件,它将使用 joomla 功能从 joomla 安装中获取您需要的一切,并在应用程序初始化时发送到您的应用程序。最重要的问题将是你的数据流建模!

                【讨论】:

                  【解决方案10】:

                  要获取 Joomla 用户 ID,请使用:

                  $user =& JFactory::getUser();
                  $user_id = $user->get('id');
                  

                  并获取用户会话 ID 使用:

                  $session = & JFactory::getSession();
                  $session_id = $session->getId();
                  

                  【讨论】:

                    【解决方案11】:

                    如果您将会话存储在数据库中,您可以按照以下评论解码会话数据:

                    http://www.php.net/manual/en/function.session-decode.php#79244

                    【讨论】:

                      【解决方案12】:

                      我假设您所说的应用程序是指另一个网站。您最好的选择是在该应用程序中使用 iframe 来实例化 Joomla 启动文件,在该 iframe 中获取用户 ID,将其与您当前的会话 ID 一起存储在数据库中的某个位置,然后由其他应用程序检索它。不过需要一些时间。

                      【讨论】:

                        【解决方案13】:

                        我将下面的代码放在 Joomla index.php 中,它对我来说很好。

                        //Set session to access it outside
                        $user =& JFactory::getUser();
                        $username = $user->get('username');

                        session_start();
                        $_SESSION['username'] = $username;

                        现在您可以在 Joomla 之外使用会话变量,如下所示

                        session_start();
                        $_SESSION['username'];

                        【讨论】:

                          【解决方案14】:

                          我不能告诉你 Joomla 版本高于 1.5 是如何做到这一点的,但在 Joomla 1.5 中你是如何做到这一点的:(我相信其他版本的程序非常类似)

                          Joomla 为网站的前端和后端生成唯一的会话 ID。 要访问会话数据,您只需要知道会话 ID。

                          在joomla配置文件中有一个参数叫“secret

                          对于后端,这是生成会话 ID 的方式:

                          $session_id = md5( md5( JConfig::$secret.'administrator' ) );
                          

                          对于前端:

                          $session_id = md5( md5( JConfig::$secret.'site' ) );
                          

                          之后是一个简单的查询

                          mysql_query( 'SELECT `data` FROM jos_session WHERE session_id="'.$sessionId.'"  )
                          

                          将使您能够访问会话数据。您所需要的只是解密它 session_decode 会话数据将在 $_SESSION 变量中。

                          不要忘记把session_start放在session_decode之前,否则它不起作用

                          【讨论】:

                            【解决方案15】:

                            Joomla 3 的解决方案,不使用任何库。

                            require_once '../configuration.php'; // load Joomla configuration file
                            $jConfig = new \JConfig();
                            $secret = $jConfig->secret;
                            $dbprefix = $jConfig->dbprefix;
                            $cookieName = md5(md5($secret . 'site'));
                            $sessionId = $_COOKIE[$cookieName];
                            $sql = "select userid from {$dbprefix}session where client_id = 0 and session_id = ?";
                            $userId = $db->lookup($sql, [$sessionId]);
                            
                            

                            (上面的代码是简化的,没有任何错误处理。)

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 2018-10-03
                              • 2014-04-05
                              • 2013-03-25
                              • 2011-03-27
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多