Bug #62194
closedLogin a FE User with PHP not possible any more in TYPO3 6.2.5
Added by Alex Kellner over 9 years ago. Updated over 3 years ago.
0%
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?
Updated by Thomas Obernberger over 9 years ago
I have the same problem
Is there a workaround for this issue?
Updated by Thilo Schumann over 9 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.
Updated by Sebastian Haak over 9 years ago
I have the same problem.
Any ideas how to handle it?
Updated by Benedict Burckhart over 9 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);
Updated by Stefan Neufeind over 9 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);
Updated by Helmut Hummel over 9 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
Updated by Helmut Hummel over 9 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();
Updated by Alex Kellner over 9 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/
Updated by Mirko grothe over 9 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
Updated by Markus Klein over 9 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);
Updated by Markus Kappe over 9 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
Updated by Alex Kellner almost 9 years ago
Ticket is not assigned to anyone. In my opinion you can close it.
Updated by Markus Klein almost 9 years ago
- Status changed from Needs Feedback to Closed
The login is possible again as described above, so all should be good.
Updated by Dennis Laudenbach almost 9 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!
Updated by Markus Klein almost 9 years ago
See my example https://forge.typo3.org/issues/62194#note-12
Updated by Dennis Laudenbach over 8 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?
Updated by Markus Klein over 8 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.
Updated by Stefan Neufeind almost 5 years ago
tried this on 8 LTS and it didn't set me a session-cookie sigh
Updated by Enrico Kaspar over 4 years ago
For me this is working:
$tsfe->fe_user->forceSetCookie = true;
$tsfe->fe_user->dontSetCookie = false;
$tsfe->fe_user->start();
Updated by varioous OG about 4 years ago
For TYPO3 9+ see https://varioous.at/blog/typo3-9-manueller-programmatischer-login.
Updated by Markus Klein about 4 years ago
@varioous OG 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);
Updated by Mathias Brodala over 3 years ago
Just chiming in to confirm that the approach Markus mention works perfectly fine. (Tested on TYPO3v10.)