I have a problem with my API. After my login, I have a token, but unfortunately I can not read the information of my user with this token.
my code to have the token (that works):
/**
* #Rest\View()
* #Rest\Post("/api/createToken")
*/
public function createTokenAction(Request $request)
{
// reception payload
$username = $request->request->get('email');
$password = $request->request->get('password');
$user = $this->getDoctrine()
->getRepository('ApplicationSonataUserBundle:User')
->findOneBy(['email' => $username]);
// check user
if (!$user) {
$response = new JsonResponse('User not found');
$response->setStatusCode(Response::HTTP_NOT_FOUND);
return $response;
}
//check password
$encoder_service = $this->get('security.encoder_factory');
$encoder = $encoder_service->getEncoder($user);
$valid = $encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt());
if (!$valid) {
$response = new JsonResponse('User Password is invalid');
$response->setStatusCode(Response::HTTP_NOT_FOUND);
return $response;
}
// store data inside my token
$token = $this->get('lexik_jwt_authentication.encoder')
->encode([
'id' => $user->getId(),
'email' => $user->getEmail(),
'exp' => time() + 3600 // 1 hour expiration
]);
$view = View::create($token);
$view->setFormat('json');
return $view;
}
then I try to use this code to read the information of my token:
/**
* #Rest\View()
* #Rest\Get("/api/user")
*/
public function getUsersAction(Request $request)
{
$response = $this->get('lexik_jwt_authentication.jwt_manager')->create($this->getUser());
$view = View::create($response);
$view->setFormat('json');
return $view;
}
but nothing does .. I do not understand why .. :/
If someone would have a track to offer me please
Related
I am using a Symfony 4 project, and I want to change the user password, so I created a method in my repository and called it to the controller, but this error it diplay to me,
Binding entities to query parameters only allowed for entities that have an identifier.
Repository
public function updateU($password,$email): ?Utilisateur
{
$dql = <<<DQL
SELECT u
FROM App\Entity\Utilisateur u
WHERE u.email = :email
AND u.password = :password
DQL;
return $this->getEntityManager()->createQuery($dql)
->setParameters(['email' => $email, 'password' => $password])
->getSingleScalarResult();
}
Controller
/**
* #Route("/Reset", name="Reset")
* Method({"GET"})
*/
public function New(
Request $request,
UtilisateurRepository $URe,
UserPasswordEncoderInterface $userPasswordEncoder,
EntityManagerInterface $entityManager,
MailerInterface $mailer
) {
$o = '';
$Varmail = $_GET['email'];
$user = new Utilisateur($o);
$form = $this->createFormBuilder($user)
->add('password', PasswordType::class)
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$to = $Varmail;
$sujet = 'Password Changed';
$Message = "Bonjour $Varmail Votre email est changé !";
$pass = $user->setPassword(
$userPasswordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
$URe->updateU($pass, $Varmail);
$Mai = new MailerController();
$Mai->sendEmail($mailer, $to, $sujet, $Message);
}
return $this->render('modifier_mdp/index.html.twig', [
'form' => $form->createView(),
]);
}
How can i solve it , And Thanks
In your updateU method, you are making a request to get, not update the data. It's better to use the ObjectManager to save the data, since you still have a updated instance of the Utilisateur object in the $user variable.
$user = $this->getDoctrine()->getManager()->getRepository(Event::class)->findOneBy(['email'=>$Varmail]);
$form = $this->createFormBuilder($user)->add('password', PasswordType::class)->getForm();
if ($form->isSubmitted() && $form->isValid()) {
// ...
$user->setPassword(
$userPasswordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
// save Utilisateur with new password
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
}
I'm doing a authentication with guard feature. Problem is than I have to put a password to my User, he don't have to know this password so I choose to generate a random password. Problem is than I'm not in a controller so I can't use UserPasswordEncoderInterface ... So I'm looking for some help here.
I give you some code :
public function getUser($credentials, UserProviderInterface $userProvider)
{
/**
* #var FacebookUser $facebookUser
*/
$facebookUser = $this->getFacebookClient()
->fetchUserFromToken($credentials);
$email = $facebookUser->getEmail();
$user = $this->em->getRepository('App:User')
->findOneBy(['email' => $email]);
if (!$user) {
$user = new User();
$user->setEmail($facebookUser->getEmail());
$user->setName($facebookUser->getFirstName());
$user->setLastName($facebookUser->getLastName());
$user->setRoles(["ROLE_USER"]);
//TODO HASH PASSWORD
$user->setPassword(bin2hex(random_bytes(80)));
$this->em->persist($user);
$this->em->flush();
}
return $user;
}
and the method from controller
/**
* After going to Facebook, you're redirected back here
* because this is the "redirect_route" you configured
* in config/packages/knpu_oauth2_client.yaml
* #Route("/connect/facebook/check", name="connect_facebook_check")
*
* #return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function connectCheckAction() {
if (!$this->getUser()) {
return new JsonResponse(array('status' => false, 'message' => "User not found!"));
} else {
// $em = $this->getDoctrine()->getManager();
//
// $user = $this->getUser();
// $password = bin2hex(random_bytes(80));
// $hash = $encoder->encodePassword($user, $password);
// $user->setPassword($hash);
//
// $em->persist($user);
// $em->flush();
return $this->redirectToRoute('default');
}
}
You can inject EncoderFactoryInterface by constructor:
/**
* #var EncoderFactoryInterface
*/
private $securityEncoderFactory;
public function __construct(EncoderFactoryInterface $securityEncoderFactory)
{
$this->securityEncoderFactory = $securityEncoderFactory;
}
And then use:
$encoder = $this->securityEncoderFactory->getEncoder($user);
$encoder->encodePassword($user, $password);
You can just use the PHP's function password_hash to hash your randomly generated password. See the documentation here
I have a problem when i try to reset password on a non loggued user.
Entity users :
class Users implements AdvancedUserInterface, \Serializable, TwoFactorInterface, TrustedDeviceInterface {
[...]
}
Reset Password Action :
public function forgetPassword(Request $request, EntityManagerInterface $em, UserPasswordEncoderInterface $encoder)
{
$changePasswordModel = new ChangePassword();
$form = $this->createForm(ForgetPasswordType::class, $changePasswordModel);
$form->handleRequest($request);
$user = $em->getRepository("App:Users")->find(12);
if (!$request->get('token') || !$user || $user->getTokenExpire() <= new \DateTime())
{
return $this->redirectToRoute("404");
}
if ($form->isSubmitted() && $form->isValid())
{
$plainPassword = $form->getData()->getNewPassword();
$encoded = $encoder->encodePassword($user, $plainPassword);
$user->setPassword($encoded);
$em->persist($user);
$em->flush();
}
return $this->render('security/forget_password.html.twig', array(
'form' => $form->createView(),
'success' => $success
));
}
But i get this error :
The User object must implement the UserInterface interface.
Exact place of this error is on :
\vendor\symfony\security\Core\Validator\Constraints\UserPasswordValidator.php :
[...]
$user = $this->tokenStorage->getToken()->getUser();
if (!$user instanceof UserInterface) {
throw new ConstraintDefinitionException('The User object must
implement the UserInterface interface.');
}
[...]
When the user is loggued it work but when an user use a reset password it's because he lost his password. So it should work when the user is not loggued.
Thanks for your help !
Alex
I'm trying to do a little API with Symfony2.
I send a session id to my controller with a URL like this:
localhost/symfony2/web/app_dev.php/users/getuser/c5auv7mrp45rnd046cfv0vgl96
Then, in Symfony,
/**
* #Route("/getuser/{sessionId}")
*/
public function getSessionAction(Request $request, $sessionId)
{
// Here is what i'm trying to do
$packJson = array(
'user_id' => $userid
);
$response = new JsonResponse();
$response->setData($packJson);
return $response;
}
So, i would like to retrieve my user Id only with the sessionId argument.
Of course, it will be load from Db
I don't understand the logic between Session object and User Objet
Thanks
I think you want to use a token to identify a user. That means you have one token for each user in your database. If that is correct then it has nothing to do with sessions or a session-object.
you could simple retrieve your user with:
/**
* #Route("/getuser/{token}")
*/
public function getSessionAction($token)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('AdminBundle:User')->findOneBy(array('token' => $token);
$response = new JsonResponse();
if (!$entity) {
$response->setData('error' => 'bad token');
return $response;
}
$packJson = array(
'user_id' => $entity->getId()
);
$response->setData($packJson);
return $response;
}
I know there was a few topics about this but I get see what I've done wrong.
my function for setting cookie is
public function createCookie($city)
{
$expire = time() + (3600 * 24 * 90);
$cookie = new Cookie('calendar_dev_city', $city, $expire, '/', 'cal.dev', false, false);
$response = new Response();
$response->headers->setCookie($cookie);
$response->sendHeaders();
}
if I dump headers right at the end of this function I can see the cookie is set but after redirection it is gone.
You have to return that Response in a controller action.
<?php
// ...
public function pageAction() {
$response = Response::create();
$cookie = $this->makeCookie();
$response->headers->setCookie($cookie);
$response->setContent('thank you for setting the cookie!');
return $response;
}
private function makeCookie() {
$cookie = new Cookie(/* */);
return $cookie;
}