简体   繁体   English

在 Joomla 之外访问会话数据

[英]Accessing session data outside Joomla

I am trying to run an application outside Joomla (not as a plugin) and I would like to access the logged in user's information (userid).我试图在 Joomla 之外运行一个应用程序(不是作为插件),我想访问登录用户的信息(用户 ID)。 I am wondering how should I go about doing that?我想知道我该怎么做? Is there a file which I can include?有我可以包含的文件吗? I tried using $_SESSION but it shows empty.我尝试使用 $_SESSION 但它显示为空。

Is there a simple solution to my problem?我的问题有简单的解决方案吗? Thank you for your time.感谢您的时间。

Actually that's not as easy as it sounds.事实上,这并不像听起来那么容易。 Joomla uses its own session handling with come unique session-id-generation and some encryption in place, so the only way to get into the Joomla session data is to use the appropriate Joomla functions (as others have suggested). Joomla 使用它自己的会话处理,带有独特的会话 ID 生成和一些适当的加密,因此进入 Joomla 会话数据的唯一方法是使用适当的 Joomla 功能(正如其他人所建议的那样)。 I recently had a project where we needed to transfer a Joomla authenticated user into a separate application.我最近有一个项目,我们需要将经过 Joomla 身份验证的用户转移到一个单独的应用程序中。 We did this by adding a Joomla adapter which instantiates the Joomla user classes, reads the user data, puts everything into an encrypted cookie and redirects back to our application.我们通过添加一个 Joomla 适配器来实现这一点,该适配器实例化 Joomla 用户类、读取用户数据、将所有内容放入加密的 cookie 中并重定向回我们的应用程序。 In there we read the encrypted cookie, instantiate our own user object and discard the cookie.在那里我们读取加密的 cookie,实例化我们自己的用户对象并丢弃 cookie。 As this is not 100% secure we're changing the system to write the user data in a database table and read it from our application - we avoid the unsecure way through a cookie that way, because even though the cookie is encrypted (and contains sensitive user information which suffice to authenticate a user) it'll be transfered on wire and could be sniffed.由于这不是 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');

The above is the basic script required to access Joomla resources.以上是访问Joomla资源所需的基本脚本。

 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';
    }

The solution is to set the session for your whole domain and/or site.解决方案是为整个域和/或站点设置会话。 It applies if you're trying to access the session data outside of joomla scope.如果您尝试访问 joomla 范围之外的会话数据,则它适用。 For example, if your joomla site is located on http://example.com/joomla/ and your other site on http://othersite.example.com/ then the cookie holding the session id is not transmitted from joomla to the other site.例如,如果您的 joomla 站点位于http://example.com/joomla/而您的其他站点位于http://othersite.example.com/则保存会话 ID 的 cookie 不会从 joomla 传输到另一个地点。 To modify this behaviour, use session_ set_ cookie_ params before every session_start() (I don't know joomla very well, but you should have to add only a few lines of code).要修改此行为,请在每个 session_start() 之前使用 session_ set_ cookie_ params (我不太了解 joomla,但您应该只需要添加几行代码)。 Use it this way:以这种方式使用它:

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

86400 is the lifetime of the session, set it to what you prefer (86400 is one day). 86400 是会话的生命周期,将其设置为您喜欢的(86400 是一天)。 '/' is the path of the cookie. '/' 是 cookie 的路径。 It means that if your joomla site is located on http://example.com/joomla/ , the session cookie will still be sent if the user accesses http://example.com/ .这意味着如果您的 joomla 站点位于http://example.com/joomla/ ,则如果用户访问http://example.com/ ,会话 cookie 仍将被发送。

'.example.com' is the domain. '.example.com' 是域。 Note the dot at the beginning, it's very important.注意开头的点,这很重要。 It says that the session cookie will be sent on any subdomain of example.com.它表示会话 cookie 将在 example.com 的任何子域上发送。 If you don't put it, the cookie will be sent only for addresses starting with http://example.com/ .如果您不输入,cookie 将仅针对以http://example.com/开头的地址发送。

This should solve your problem, unless you are trying to access the session data from another domain.这应该可以解决您的问题,除非您尝试从另一个域访问会话数据。 If it's the case, leave a comment here, I'll see if I cand find something.如果是这样,请在此处发表评论,我会看看是否可以找到一些东西。

First of all you have to provide definition to some joomla's constants(identifiers) as follows:首先,您必须为某些 joomla 的常量(标识符)提供定义,如下所示:

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

where: JPATH_BASE is represents your site's root directory.其中: JPATH_BASE 代表您站点的根目录。 It must be correct.它必须是正确的。

After than, you have to use key files as follows:之后,您必须按如下方式使用密钥文件:

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

After than, you have to create an application object and initialize it also:之后,您必须创建一个应用程序对象并对其进行初始化:

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

[this is optional] If you want to import some other libraries, then you can do this as follows: [这是可选的] 如果你想导入一些其他的库,那么你可以这样做:

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

So the core code for your file is as follows:所以你的文件的核心代码如下:

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');

The solution showed by Stefan Gehrig 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');

works fine, I have spent many long nights trying access the Joomla!工作正常,我花了很多个漫长的夜晚试图访问 Joomla! resources outside the joomla folder. joomla 文件夹外的资源。

$session     = &JFactory::getSession();

In the follow up code, works fine when the getApplication method has been invoked.在后续代码中, getApplication方法时工作正常。

Thanks for solution.感谢您的解决方案。

to get the user id you need to use Joomlas functions:要获取您需要使用 Joomlas 功能的用户 ID:

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

will let you get the user ID.会让你得到用户ID。 you will however need to do this inside of the joomla page so i dont know how usefult hat will be to you.但是,您需要在 joomla 页面内执行此操作,因此我不知道这对您有多大用处。

apply this in mod_login.phpmod_login.php应用它

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

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

It is very possible that like Wordpress, Joomla doesn't use any 'session' data, but rather pulls data directly from the database.很可能像 Wordpress 一样,Joomla 不使用任何“会话”数据,而是直接从数据库中提取数据。 In which case you would need to use Joomla's native functions.在这种情况下,您需要使用 Joomla 的本机功能。

But that is just from my experience with Wordpress.但这只是根据我使用 Wordpress 的经验。

Updated更新

I guess I was wrong.我想我错了。
Supposidly this is the api class for accessing Joomla Session variables:假设这是访问 Joomla Session 变量的 api 类:

// Returns a reference to the global JSession object, only creating it if it doesn't already exist $session = &JFactory::getSession(); // 返回对全局 JSession 对象的引用,仅在它不存在时才创建它 $session = &JFactory::getSession();

// Get a value from a session var $value = $session->get('var_name', null); // 从会话中获取一个值 var $value = $session->get('var_name', null);

// Put a value in a session var $session->set('var_name', $value); // 在会话中放入一个值 var $session->set('var_name', $value);

It might be helpful to see how such is achieved in application bridges like jFusion.了解如何在 jFusion 等应用程序桥接中实现这一点可能会有所帮助。 I suggest at least a system plugin for Joomla, that will use joomla functions to get everything you need from the joomla install and shipto your application onApplicationInitialize.我建议至少为 Joomla 安装一个系统插件,它将使用 joomla 功能从 joomla 安装中获取您需要的一切,并在 ApplicationInitialize 上发送到您的应用程序。 The most important issue will be ur data flow modelling!最重要的问题将是您的数据流建模!

I put below code in Joomla index.php and it's work fine for me.我把下面的代码放在 Joomla index.php 中,它对我来说很好用。

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

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

Now you can use session variable outside Joomla as below现在您可以在 Joomla 之外使用会话变量,如下所示

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

I cannot tell you how Joomla with versions above 1.5 does that but in Joomla 1.5 here is how you do that: ( I am sure for other versions procedure is very similar )我不能告诉你的Joomla与上述版本1.5请问是怎么但是在1.5的Joomla这里是你如何做到这一点:(我相信对于其他版本的程序非常相似)

Joomla generates Unique session id for front-end of the website and back-end. Joomla 为网站的前端和后端生成唯一的会话 ID。 To access session data all you need is know the session id.要访问会话数据,您只需要知道会话 ID。

In joomla configuration file there is a parameter called " secret "在 joomla 配置文件中有一个名为“ secret ”的参数

For back-end this is how you generate session id:对于后端,这是生成会话 ID 的方式:

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

and for front end:对于前端:

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

After this a simple query在此之后一个简单的查询

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

will give you access to session data.将使您能够访问会话数据。 All you need is to decrypt it with session_decode and session data will be in $_SESSION variable.您只需要使用session_decode解密它,会话数据将在$_SESSION变量中。

Don't forget to put session_start before session_decode otherwise it will not work不要忘了把在session_startsession_decode否则将无法正常工作

To get Joomla user id use:要获取 Joomla 用户 ID,请使用:

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

and to get user session id use:并获取用户会话 ID 使用:

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

If you store your sessions in database, you could decode session data as in this comment:如果您将会话存储在数据库中,则可以按照以下注释对会话数据进行解码:

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

A solution for Joomla 3, without using any libraries. 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]);

(The code above is simplified, without any error handling.) (上面的代码是简化的,没有任何错误处理。)

I assume that by application you mean another website.我假设您所说的应用程序是指另一个网站。 Your best bet is to have an iframe in that application instantiating the Joomla startup file, get the user id in that iframe, store it somewhere in the database along with your current session id, and then retrieve it by the other application.最好的办法是在该应用程序中使用 iframe 实例化 Joomla 启动文件,在该 iframe 中获取用户 ID,将其与当前会话 ID 一起存储在数据库中的某个位置,然后由其他应用程序检索它。 Will take some time though.不过需要一些时间。

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

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