I am trying to understand PHP login system using this php-login-advanced by panique. The code snippet for register.php is:
<?php
// check for minimum PHP version
if (version_compare(PHP_VERSION, '5.3.7', '<')) {
exit('Sorry, this script does not run on a PHP version smaller than 5.3.7 !');
} else if (version_compare(PHP_VERSION, '5.5.0', '<')) {
// if you are using PHP 5.3 or PHP 5.4 you have to include the password_api_compatibility_library.php
// (this library adds the PHP 5.5 password hashing functions to older versions of PHP)
require_once('libraries/password_compatibility_library.php');
}
// include the config
require_once('config/config.php');
// include the to-be-used language, english by default. feel free to translate your project and include something else
require_once('translations/en.php');
// include the PHPMailer library
require_once('libraries/PHPMailer.php');
// load the registration class
require_once('classes/Registration.php');
// create the registration object. when this object is created, it will do all registration stuff automatically
// so this single line handles the entire registration process.
$registration = new Registration();
// showing the register view (with the registration form, and messages/errors)
include("views/register.php");
and in class Registration the constructor is:
public function __construct()
{
session_start();
// if we have such a POST request, call the registerNewUser() method
if (isset($_POST["register"])) {
$this->registerNewUser($_POST['user_name'], $_POST['user_email'], $_POST['user_password_new'], $_POST['user_password_repeat'], $_POST["captcha"]);
// if we have such a GET request, call the verifyNewUser() method
} else if (isset($_GET["id"]) && isset($_GET["verification_code"])) {
$this->verifyNewUser($_GET["id"], $_GET["verification_code"]);
}
}
On line $registration = new Registration(); a new object of type Registration is created and it's constructor is called on Server-Side. The Server calls session_start() function. If a valid Session-ID was sent by client then file corresponding to that Session-ID is loaded in $_SESSION variable or else a new Session-ID is generated and is sent to client to store that in a COOKIE to maintain the session. The rendered register.php page is sent to client. Client fills form and submits. The values of form get stored in the $_POST array on Server-Side and this time when NEW object of class Registration is created the other two lines are also executed and the user is registered.
My Question is:
Am I understanding correctly the lifetime of $_POST, $_SESSION and the Registration Object? A better explanation is most welcome.
Related
i have two methods:
method one catch the username and password
method 2 is a service that should catch the username and password through custom request headers
i want to add the username and password as custom headers to the current request so method 2 can handle them
method 2 has one parameter which is IRequest
i'm using OwnCloud, trying to make a plugin app to control Authentication, this works when calling OwnCloud through webdav in C# but i need it to control OwnCloud login page also by catching userName and password and use the same code in the module object
how can add new headers to the current request call since the header("..") function not working?
class Application extends App {
public function pre_login($parameters) { // method 1
$uid = $parameters['uid'];
$password = $parameters['password'];
header("UserId:" . $uid);
header("Password:" . $password);
}
}
class AuthModule implements IAuthModule {
public function auth(IRequest $request) { // method 2
$UserId = $request->getHeader('UserId'); // not working
$password= $request->getHeader('password'); // not working
}
}
If you have 2 different apps and want to get headers (on your api for example) take into account that some frameworks add additional info to headers. Try getHeader('HTTP_UserId')
I have a LoginController where I do my usual login operation with combination of an email address and a password associated with the account.
I have separated my Hybridauth related code into a separate controller named OauthController where I have all my Hybridauth magic and where my callback / endpoint resides.
In the OauthController I check if user's email from the specified provider is already registered, and in either case I try to login that user with $this->Auth->setUser(object).
Whenever, or whatever from the $this->Auth is called, I get a response stating:
Session was already started
I have browser through CakePHP 3 code and found the following statement in:
vendor/cakephp/cakephp/src/Network/Session.php (335)
public function start()
{
if ($this->_started) {
return true;
}
if ($this->_isCLI) {
$_SESSION = [];
$this->id('cli');
return $this->_started = true;
}
if (session_status() === \PHP_SESSION_ACTIVE) {
throw new RuntimeException('Session was already started');
}
...
And that's the point in code where that message is thrown at me.
Now, as I browsed through the Hybridauth code itself, I have found following in:
vendor/hybridauth/hybridauth/src/Storage/Session.php (46)
public function __construct()
{
if (session_id()) {
return;
}
if (headers_sent()) {
throw new RuntimeException('HTTP headers already sent to browser and Hybridauth won\'t be able to start/resume PHP session. To resolve this, session_start() must be called before outputing any data.');
}
if (! session_start()) {
throw new RuntimeException('PHP session failed to start.');
}
}
And both of them call session_start, one before the other, although CakePHP's part is blocking me.
I have tried removing !session_start() check from Hybridauth, but then Hybridauth doesn't know where to read out it's thingies it needs to read.
So, as a demonstrator, I am trying to achieve this in OauthController:
<?php
namespace App\Controller;
use Hybridauth\Hybridauth;
class OauthController extends AppController
{
public function callback($provider)
{
try {
$hybridauth = new Hybridauth($config);
// additional mystery code
$hybridauth->authenticate();
if($everything_okay) {
$this->Auth->setUser($userObject); // and this is the point of failure
return $this->redirect('/account'); // and this never happends... :(
}
}
}
}
Any help, ideas, insights on how to deal with this are all welcome!
Simply start the CakePHP session manually before using the Hybridauth library, so that it bails out at the session_id() check and picks up the existing session.
For example in your controller:
$this->getRequest()->getSession()->start();
// in CakePHP versions before 3.6/3.5
// $this->request->session()->start();
I'm trying to implement a SessionProvider auth plugin for a mediawiki install.
I'm trying to integrate with an existing auth system that uses $_SESSION to indicate that a user is logged in, however any method I try, the resulting $_SESSION variable that I get inside the class' provideSessionInfo function is empty.
Previously this was done with a onUserLoadFromSession hook (that contained the bulk of the logic code below), but the update appears to have broken actually looking at the existing $_SESSION:
public function provideSessionInfo(WebRequest $request)
{
// $_SESSION is hidden away per-request, but $request->getSession likes to call this function (yay infinite loops)
if (!isset($_SESSION['memberid'])) {
return null;
}
$memberid = $_SESSION['memberid'];
$mr_user = MyRadio_User::getInstance($memberid);
$user = User::newFromName($memberid);
$dbr = wfGetDB(DB_REPLICA);
$s = $dbr->selectRow('user', ['user_id'], ['user_name' => $memberid]);
if ($s === false) {
return null;
} else {
$user->mName = $memberid;
$user->mId = $user->idForName();
$user->loadFromDatabase();
$user->saveSettings();
}
if ($mr_user->hasAuth(AUTH_WIKIADMIN) && !in_array('sysop', $user->getGroups())) {
$user->addGroup('sysop');
}
$user->mTouched = wfTimestampnow();
return new SessionInfo(SessionInfo::MAX_PRIORITY, [
'provider' => $this,
'persisted' => true,
'userInfo' => UserInfo::newFromUser($user, true),
]);
}
If I hardcode $memberid, the function and the session provider works fine, but I just can't seem to find a way to transfer the session from one PHP "application" to another.
Adding debugging shows the PHPSESSID variable still set in the cookie, but for whatever reason it can't be pulled out into an actual session object. I've tried various session_start() style methods to no effect.
I feel like I'm missing something obvious, but the documentation for this stuff is just a basic wiki page and the raw generated doxygen.
Session handling is not a good way of cross-application communication. MediaWiki uses its own session handling, which means there is no connection between $_SESSION in MediaWiki and $_SESSION in your application at all. The first will be populated from MediaWiki's object cache (as configured by $wgSessionCacheType), the other from PHP session files or whatever.
If you really do not have a better way to pass data, you'll have to write a custom access class which can be called by your provider, which will save the current session handler, install a null session handler (which restores PHP's native session handling which will hopefully be interoperable with the other application), start the session, fetch the session data, restore the original session handler, and probably start the session again.
I'm using joomla 3++.
I'm calling a method from my component's class in my system plugin. Prior to calling this method, I wish to check if it's already been called?
public function onAfterInitialise()
{
MyClass::initialize();
}
if (class_exists('MyClass'))//always true when navigate among different components
if (method_exists('MyClass', 'initialize'))//always true also
var_dump(MyClass::initialize());//true
The problem I'm facing:
My system plugin is not running on other components if I don't call this MyClass::initialize().
At the same time, one of the components says a js file is already loaded if I called MyClass::initialize() at onAfterInitialize()
So I'm thinking probably to avoid a
xx.js file loaded already issue,
I could check first this MyClass::initialize() called or not.
you are calling MyClass::initialize() method right?, in that method use
JFactory::getSession()->set('init_called',1,'your_component');
in system plugin you can check
public function onAfterInitialise()
{
$is_called = JFactory::getSession()->get('init_called','','your_component');
if($is_called){
//already called, do any other code
}else{
// Not yet called, do any other code
}
}
Now you can check that function already called, make sure session will not clear until logout. any other place clear session use this
JFactory::getSession()->clear('init_called','your_component');
My Code:
class cdbsHandler
{
[...]
private $link;
function __construct($mysqld)
{
[...]
$this->link = mysql_connect(
$mysqld['host'], $mysqld['user'], $mysqld['password']
);
mysql_select_db($mysqld['database'], $this->link);
}
function write($sessionId, $data)
{
$sessionId = mysql_real_escape_string($sessionId, $this->link);
}
[...]
}
I use the class like this:
static function startSession($name, $mysqld)
{
[...]
$sessionHandler = new cdbsHandler($mysqld);
session_set_save_handler(
array ($sessionHandler,"open"),
array ($sessionHandler,"close"),array ($sessionHandler,"read"),
array ($sessionHandler,"write"),array ($sessionHandler,"destroy"),
array ($sessionHandler,"gc")
);
session_start();
}
Where $mysqld are the database credentials.
The static function is called every time that a user loads a page.
The error I get is:
mysql_real_escape_string(): 2 is not a valid MySQL-Link resource
(calling mysql_real_escape_string in the write function)
The credentials are correct. They are loaded from a config file and are successfully used to establish a connection a few lines after the session was started.
What seems very important to me:
I am actually able to login and data is written to the database (/session) but as soon as the login page redirects me to the home page the error mentioned above appears.
(The login page verifies a form token that is saved in the session data. But after sending that request the script isn't able to access any session data anymore.)
More Information:
The code is from a memcached session handler with database "backup".
Most likely this is what's happening (best guess based on your information):
Per the manual the session write handler is not called until after the script has ended. In many versions of PHP, all class destructors are run before calling the session write handler. Consequently, if you are closing the connection in __destruct(), then __destruct() is called before write() is - leading to an invalid connection when you try to save the session.