i try to login the user manually after the registration with this code:
http://www.michelsalib.com/2011/04/pragmatically-authenticate-the-user-in-symfony2/
Its not working with the fresh created user, but when i login an other existing user after a userregistation, everything works fine.
I thought the user object isn't complete but i tried to read the registrerd user again and it doesn't work too.
Has anyone an idea what the problem is?
Thank you very much
You have to create a new token and pass it to the security context.
// Create a new token
$token = new UsernamePasswordToken($user, $credentials, $providerKey, $user->getRoles());
// Retrieve the security context and set the token
$context = $this->container->get('security.context');
$context->setToken($token);
Related
On my platform, the administrator create a user where the password is randomly generated and this automatically sends an email to this new user. The email contains a link that leads to the reset-password page (which will be a password creation page for the user because he does not know that he already has a password generated).
The problem is that when the user clicks on the email link and arrives on the change password page, he is logged in as admin and therefore has permissions that he should not have.
In fact, I want the email link to connect the new user to his account, I don't want him to be logged in as admin. I'm not sure how to do this.
I don't know much about tokens. I believe the Token is generated based on the session used (?).
Thank you in advance for your help.
Here is the code for creating a user :
/**
* #Route("/new", name="user_new", methods={"GET", "POST"})
* #throws TransportExceptionInterface
*/
public function new(Request $request, MailSender $mailSender,UserPasswordHasherInterface $passwordHasher): Response
{
// TODO CHECK IF USER ALREADY EXISTS BY EMAIL
$user = new User();
$form = $this
->createForm(UserType::class, $user)
->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// TODO GENERATE RANDOM PASSWORD
//$passwordHasher->hashPassword($user, $user->getPassword()));
$user->setPassword($passwordHasher->hashPassword($user, "password"));
$this->entityManager->persist($user);
$this->entityManager->flush();
try {
$resetToken = $mailSender->makeToken($user);
} catch (ResetPasswordExceptionInterface $e) {
return $this->redirectToRoute('user_new');
}
$mailInfos = array('template'=>"reset_password/email_activate.html.twig", 'subject'=>"Activer votre compte", 'email'=>$user->getEmail());
$mailSender->sendMail($resetToken, $mailInfos);
$mailSender->storeToken($resetToken);
return $this->redirectToRoute('user_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('user/new.html.twig', [
'user' => $user,
'form' => $form,
]);
}
This is expected behaviour because:
multiple tabs/instances of the same browser will usually share the
same server-side session when interacting with the same domain.
means that you can´t be logged in with different users in different tabs per default.
And I don´t think that you would want this, just think of the downsides, do you really want to login again for every tab? This is very uncommon practice. Imagine you would open a stack-overflow question in a new tab and you would not be logged in there.
There are ways to achieve this though, but really re-think if thats your actual usecase, i don´t think so, you are just developing your feature and testing it, and in production a new user will not be already logged in as admin is my assumption.
So for testing your feature just use a private tab (that does usually not share the same server-side session )
if you want to learn more i found this pretty cool so-thread where users try to explain as best as possible
What are sessions? How do they work?
I want to login a user after registration successfully. Currently the solution I found online is login a user in a session basis. But I need the "remember me" feature. My research lead me to the
Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices
and its function
onLoginSuccess
But I'm out of luck and end up with circular reference detected for service. Also the onLoginSuccess is protected function. I assume I can duplicate those functions in my own function where performing a login feature. But that's always not a good choice. So I'd like to learn if anyone had experience on that?
Here I had my own answer.
First, login user with following snippet
$user = new \AppBundle\Security\User\EndUser($id, $userKey, $username, $password, $salt, $roles);
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->container->get('security.token_storage')->setToken($token);
$this->container->get('session')->set('_security_main', serialize($token));
Be aware that your own userProvider or EndUser maybe different from mine. Change the $user accordingly to make it work in your own situation.
Second, implement the remember me feature.
$file = sprintf("%s/config/security.yml", $this->container->getParameter('kernel.root_dir'));
$parsed = Yaml::parse(file_get_contents($file));
$options = $parsed['security']['firewalls']['main']['remember_me'];
$endUserProvider = $this->container->get('AppBundle\Security\User\EndUserProvider');
$secret = $providerKey = $this->container->getParameter('secret');
$service = new TokenBasedRememberMeServices(array($endUserProvider), $secret, $providerKey, $options, null);
$r = new \ReflectionMethod($service, 'onLoginSuccess');
$r->setAccessible(true);
$r->invoke($service, $request, $response, $token);
Some explanation here. Above code is firstly fetch remember me configuration for security.yml which is needed to initiate TokenBasedRememberMeServices instance. Then use the ReflectionMethod to overcome the accessible issue because method onLoginSuccess is originally protected.
This solution is tested under symfony 3.3.16. Hope this help others.
I am using Laravel + Facebook SDK ( https://github.com/SammyK/LaravelFacebookSdk) to get a friends list from my app. The weird thing is for some reason that I don't know why, some users I can fetch their friends, some users I can't.
For example, under my own user, I can fetch all my friends who are also using my app.
However, I have created a new user in Facebook just for testing. I've became a friend of this new user. In addition, this user has approved the app in their facebook. As a result, I can't see this user in my friends list and also this new user can't see me in their friends list.
My code base is
$q = \Facebook::get('/me/friends', $token);
$friends = json_decode($q->getBody())->data;
Facebook V2.0 upgraded. So you can try like this "user_friends".
Refer Link
I just figure out what was wrong! I was logging in the Facebook without the right permission scope.
Every login it must pass as a parameter "user_friends" according to this url https://developers.facebook.com/docs/facebook-login/permissions and https://developers.facebook.com/docs/php/howto/example_facebook_login
Basically, the code is
$fb = new Facebook\Facebook([
'app_id' => '{app-id}', // Replace {app-id} with your app id
'app_secret' => '{app-secret}',
'default_graph_version' => 'v2.2',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email']; // Optional permissions
$loginUrl = $helper->getLoginUrl('https://example.com/fb-callback.php', $permissions);
I know this question is already asked but I can't get it to work and I can't see what I'm doing wrong.
I'm trying to write a test for a function which depends on a user logged in and gets user object from security.token_storage but unfortunately I can't get it work. For setting up the token my code is
$token = new UsernamePasswordToken(
$person,
$person->getPassword(),
'sso',
$person->getRoles()
);
$containerInterface->get('security.token_storage')->setToken($token);
$containerInterface->get('event_dispatcher')->dispatch(
AuthenticationEvents::AUTHENTICATION_SUCCESS,
new AuthenticationEvent($token)
);
where $person is user object and 'sso' is firewall name. When I run a test where I get user object from token_storage I get null.
If I understood correctly, you're missing the login event
$event = new InteractiveLoginEvent($request, $token);
$this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
Also, but I'm not sure of, you don't need this snippet
$containerInterface->get('event_dispatcher')->dispatch(
AuthenticationEvents::AUTHENTICATION_SUCCESS,
new AuthenticationEvent($token)
);
This question already has answers here:
How to programmatically login/authenticate a user?
(7 answers)
Closed 9 years ago.
I have a controller that is supposed to add a user through a simple form, but I cannot get the user to be manually authenticated.
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
public function addAction($user)
{
$token =new UsernamePasswordToken(
$user->getUsername(),
$user->getPassword(),
'secured_area',
$user->getRoles()
);
$this->get('security.context')->setToken($token);
// as suggested in some other answers
$request->getSession()->set('_security_secured_area', serialize($token));
// as suggested in http://techblog.zabuchy.net/2012/manually-authenticate-symfony-2-user/
return $this->redirect($this->generateUrl('acme_project_secure_show' )
);
}
}
The redirection to the secure route works, but then the method $this->getUser() returns null as the authentication is not set properly...
I can get the user from $user= $this->get('security.context')->getToken(); instead of $user= $this->get('security.context')->getToken()->getUser(); shortcut for $this->getUser() see the Book here
Any idea why?
Problem solved - two points were missing: 1) it was necessary to dispatch the InteractiveLoginEvent -thanks mpm for the link 2) the route of this controller was not under the secured_area firewall - merci Florian ;)
You can try this
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
$token = new UsernamePasswordToken($user, $user->getPassword(), "firewallname", $user->getRoles());
As said #user19340357, you can instanciate a token by hand.
What he forgot to say is that you should set it in the security context:
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
$token = new UsernamePasswordToken($user, $user->getPassword(), "firewallname", $user->getRoles());
$securityContext = $this->container->get('security.context'); // do it your way
$securityContext->setToken($token);