Bug #62194

Login a FE User with PHP not possible any more in TYPO3 6.2.5

Added by Alex Kellner about 6 years ago. Updated about 2 months ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
-
Target version:
-
Start date:
2014-10-13
Due date:
% Done:

0%

TYPO3 Version:
6.2
PHP Version:
Tags:
Complexity:
Is Regression:
No
Sprint Focus:

Description

Related to Ticket #60264

In TYPO3 <= 6.2.4 it was possible to login a FE User via userFunc or in a controller with:

$GLOBALS['TSFE']->fe_user->checkPid = '';
$info = $GLOBALS['TSFE']->fe_user->getAuthInfoArray();
$user = $GLOBALS['TSFE']->fe_user->fetchUserRecord($info['db_user'], $username);
$GLOBALS['TSFE']->fe_user->createUserSession($user);
$GLOBALS['TSFE']->fe_user->user = $GLOBALS['TSFE']->fe_user->fetchUserSession();

Now it's not possible any more to login an user because the call of method $this->setSessionCookie(); in createUserSession() (typo3/sysext/frontend/Classes/Authentication/FrontendUserAuthentication.php) is missing.

Is this a breaking change?
If your changes are correct, what is the correct way to login a FE User?


Related issues

Related to TYPO3 Core - Bug #60264: felogin permalogin not working with typo3 6.2.x -> cookie expires with session Closed 2014-07-11

History

#1 Updated by Thomas Obernberger about 6 years ago

I have the same problem

Is there a workaround for this issue?

#2 Updated by Christian Wolfram about 6 years ago

I have the same problem

#3 Updated by Benjamin Butschell about 6 years ago

Same problem here.

#4 Updated by Thilo Schumann almost 6 years ago

I am having the same problem and it took me hours to figure it out.

It is also mentioned in the sysext frontend here: https://forge.typo3.org/projects/typo3cms-core/repository/revisions/master/entry/typo3/sysext/frontend/Classes/Authentication/FrontendUserAuthentication.php#L251

The problem is fixed by adding this call.

#5 Updated by Sebastian Haak almost 6 years ago

I have the same problem.

Any ideas how to handle it?

#6 Updated by Benedict Burckhart almost 6 years ago

Here is a really dirty fix for the extensions. But it should work until the bug is resolved.

$reflection = new \ReflectionClass($GLOBALS['TSFE']->fe_user);
$setSessionCookieMethod = $reflection->getMethod('setSessionCookie');
$setSessionCookieMethod->setAccessible(TRUE);
$setSessionCookieMethod->invoke($GLOBALS['TSFE']->fe_user);

Should be called after:

$GLOBALS['TSFE']->fe_user->createUserSession($user);

#7 Updated by Stefan Neufeind almost 6 years ago

In the comments in gerrit at https://review.typo3.org/31607 it was mentioned:
[...]
Markus mentioned on Slack that adding a dummy value to the session data forces to set a cookie:
$frontEndUser->setKey('ses', 'dummy', TRUE);

#8 Updated by Helmut Hummel almost 6 years ago

  • Status changed from New to Needs Feedback

The correct way (API) to authenticate a user is through a login service.
Anything else is working around the API or using internal API, which will cause unexpected behavior.

If someone comes up with a well described use case, I'm happy to help how to do this using the login service API

#9 Updated by Helmut Hummel almost 6 years ago

If you like to go on with dirty hacks (which might break in the future), this should do the trick:

$GLOBALS['TSFE']->fe_user->checkPid = '';
$info = $GLOBALS['TSFE']->fe_user->getAuthInfoArray();
$user = $GLOBALS['TSFE']->fe_user->fetchUserRecord($info['db_user'], $username);
$GLOBALS['TSFE']->fe_user->forceSetCookie = TRUE;
$GLOBALS['TSFE']->fe_user->createUserSession($user);
$GLOBALS['TSFE']->fe_user->user = $GLOBALS['TSFE']->fe_user->fetchUserSession();

#10 Updated by Alex Kellner almost 6 years ago

Thx for the information. At my point of view, this ticket can be closed now.

But nevertheless: I did not test it but I found an old blog entry which describes how to use an own auth service, if anyone needs a link:
http://jimsuperfly.de/blog/typo3-auth-service/

#11 Updated by Mirko grothe almost 6 years ago

My Logic for automatic Login with php.

$info = $GLOBALS['TSFE']->fe_user->getAuthInfoArray();
$user = $GLOBALS['TSFE']->fe_user->fetchUserRecord($info['db_user'],$loginData['uname']);
$login_success = $GLOBALS['TSFE']->fe_user->compareUident($user,$loginData);
if($login_success){
     $userSession = $GLOBALS['TSFE']->fe_user->createUserSession($user);
     $GLOBALS["TSFE"]->fe_user->loginSessionStarted = TRUE;
     $GLOBALS["TSFE"]->fe_user->user = $GLOBALS["TSFE"]->fe_user->fetchUserSession();
     return true;
} else {
    return false;
}

  • function compareUident ($login_success) return false.
  • I see the problem in line 1491 ...
  • ../6.2.9/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
  • Field $logindata['uident_text'] does not exist
  • is expected the password
  • changes to the field name in uident everything is ok

#12 Updated by Markus Klein almost 6 years ago

Hi highly recommend to autologin a user by only creating the session and force a redirect afterwards.
This is the only way the Core will correctly initialize all parts of the system. (Show correct menus etc)

Sample code:

$tsfe = $this->getTypoScriptFrontendController();
$tsfe->fe_user->createUserSession($feUser);
// enforce session so we get a FE cookie, otherwise autologin does not work (TYPO3 6.2.5+)
$tsfe->fe_user->setAndSaveSessionData('dummy', TRUE);
$this->cObj->typolink(
    '',
    [
        'parameter' => 123
    ]
);
$url = $this->cObj->lastTypoLinkUrl;
HttpUtility::redirect($url, HttpUtility::HTTP_STATUS_303);

#13 Updated by Markus Kappe over 5 years ago

Can anyone please provide an example to a login service using TYPO3 6.2 (i.e. that makes use of namespaces etc.)?

Thank you

#14 Updated by Markus Klein over 5 years ago

May I close this ticket?

#15 Updated by Alex Kellner over 5 years ago

Ticket is not assigned to anyone. In my opinion you can close it.

#16 Updated by Markus Klein over 5 years ago

  • Status changed from Needs Feedback to Closed

The login is possible again as described above, so all should be good.

#17 Updated by Dennis Laudenbach over 5 years ago

Updated by Markus Kappe 6 months ago
Can anyone please provide an example to a login service using TYPO3 6.2 (i.e. that makes use of namespaces etc.)?

No answer

Updated by Markus Klein about 1 month ago
The login is possible again as described above, so all should be good.

There are serveral ways described above...which one do you mean?

My sample Code:

protected function loginUser($username, $password) {

    $GLOBALS['TSFE']->fe_user->checkPid = '';
    $info = $GLOBALS['TSFE']->fe_user->getAuthInfoArray();
    $user = $GLOBALS['TSFE']->fe_user->fetchUserRecord($info['db_user'], $username);
    $loginData = array('uname' => $username, 'uident' => $password, 'status' => 'login');

    $GLOBALS['TSFE']->fe_user->forceSetCookie = TRUE;
    $GLOBALS['TSFE']->fe_user->createUserSession($user);
    $GLOBALS['TSFE']->fe_user->user = $GLOBALS['TSFE']->fe_user->fetchUserSession();

    $loginSuccess = $GLOBALS['TSFE']->fe_user->compareUident($user, $loginData);

    \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($loginSuccess);
    die('login');
}

Dumps "False" in TYPO3 6.2.12

So could you please post a tested example before you close the ticket?

Thank you!

#19 Updated by Dennis Laudenbach about 5 years ago

Your code breaks with the first line...you´re using $this but in which context?
Alex and all others were talking about "login a FE User via userFunc or in a controller".

class UserController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController{
  protected function loginUser($username, $password){
    $tsfe = $this->getTypoScriptFrontendController();
  }
}

-> Call to undefined method Vendor\Plugin\Controller\UserController::getTypoScriptFrontendController()

The solution migth be easy for TYPO3 Core Members...but there are people out there who are not.
So please with sugar on top: Don´t drop just some lines of code and say: It works!

Helmut Hummel: If someone comes up with a well described use case, I'm happy to help how to do this using the login service API

Imagine a booking extension with views: list, detail, login, order, end

Customers can browse through a list of items, view an item in detail view and order an item.
By clicking on order, the customer comes to a login form.

It is possible to:
register = register > login > order > end
login = login > order > end
continue as guest = order > end

How to login a fe_user within my UserController in TYPO3 6.2 with Extbase and Namespaces?

#20 Updated by Markus Klein about 5 years ago

Dennis: I assume that a developer has some basic knowledge about TYPO3 and therefore knows that @getTypoScriptFrontendController is not defined by default. The sample code stems from a pibase ext of mine with this very function added by myself. I use these kind of wrapper functions to access the global objects, in this case $GLOBALS['TSFE']. So please don't blame anyone for posting a snippet that does not work out of the box, but think about the code and ask if you fail to understand it. This is perfectly fine and I am (we are) willing to explain the bits and pieces.

Alex and all others were talking about "login a FE User via userFunc or in a controller".

As I wrote above already I strictly advise to not do any login magic on your own, but let the Core do that work for you.
So you do not "login a FE user in a controller", but you create a session for a given fe_user and let the Core take care of the login by issuing a redirect.

Regarding your use-case: The login procedure is independent of the framework you use (extbase or pibase). In the create action of your registration form (where you effectively create the fe_user in the DB), you simply run

$tsfe = $GLOBALS['TSFE'];
$tsfe->fe_user->createUserSession($feUser);
// enforce session so we get a FE cookie, otherwise autologin does not work (TYPO3 6.2.5+)
$tsfe->fe_user->setAndSaveSessionData('dummy', TRUE);

(Check the createUserSession method and see what the parameter data must be.)

After that you do a redirect to your next action and you're good.

#21 Updated by Stefan Neufeind over 1 year ago

tried this on 8 LTS and it didn't set me a session-cookie sigh

#22 Updated by Enrico Kaspar about 1 year ago

For me this is working:

        $tsfe->fe_user->forceSetCookie = true;
        $tsfe->fe_user->dontSetCookie = false;
        $tsfe->fe_user->start();

#24 Updated by Markus Klein 8 months ago

@varioous I disagree on this approach. Foremost due to the reason that you change the authentication level of request within some arbitrary controller. Despite this being at least questionable from a security perspective it can cause various side effects on the remaining rendering of the page, depending when your action is triggered.

I rather recommend upgrading the current authentication level and doing a direct redirect afterwards, so the Core can do its thing. Benefit: No password fiddling or whatsoever required.

        $feUserData = ... // fe_users record from database
        $tsfe = $GLOBALS['TSFE'];
        // ensure a session cookie is set (in case there is no session yet)
        $tsfe->fe_user->setAndSaveSessionData('dummy', true);
        // create the session (destroys all existing session data in the session backend!)
        $tsfe->fe_user->createUserSession($feUserData);
        // write the session data again to the session backend; preserves what was there before!!
        $tsfe->fe_user->setAndSaveSessionData('dummy', true);

        $url = $tsfe->cObj->typoLink_URL(
            ['parameter' => $somePageUid]
        );
        HttpUtility::redirect($url, HttpUtility::HTTP_STATUS_303);

#25 Updated by Mathias Brodala about 2 months ago

Just chiming in to confirm that the approach Markus mention works perfectly fine. (Tested on TYPO3v10.)

Also available in: Atom PDF