Я создаю свой первый проект в рамках Symfony.
Я выбрал версию 4.0. У меня есть вопрос о создании форм.
конфиг / routes.yaml
home:
path: /
controller: App\Controller\HomeController::index
methods: [GET]
login:
path: /login
controller: App\Controller\HomeController::login
methods: [POST]
register:
path: /register
controller: App\Controller\HomeController::register
methods: [POST]
timeline:
path: /timeline
controller: App\Controller\TimelineController::index
methods: [GET]
SRC / Entity / User.php
//
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @ORM\Table(name="users")
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=50)
*/
private $username;
/**
* @ORM\Column(type="string", length=100)
*/
private $email;
/**
* @ORM\Column(type="string", length=100)
*/
private $password;
/**
* @ORM\Column(type="string", length=50)
*/
private $firstName;
/**
* @ORM\Column(type="string", length=50)
*/
private $lastName;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
public function getId()
{
return $this->id;
}
public function getUsername()
{
return $this->username;
}
public function getEmail()
{
return $this->email;
}
public function getPassword()
{
return $this->password;
}
public function getFirstName()
{
return $this->firstName;
}
public function getLastName()
{
return $this->lastName;
}
public function getCreatedAt()
{
return $this->createdAt;
}
public function setUsername($username)
{
$this->username = $username;
}
public function setEmail($email)
{
$this->email = $email;
}
public function setPassword($password)
{
$this->password = $password;
}
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
}
}
SRC / Controller / HomeController.php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Entity\User;
class HomeController extends Controller
{
public function index() {
return $this->render('home/index.html.twig');
}
public function login(Request $request) {
// ?????
}
public function register(Request $request) {
$user = new User();
// ?????
}
}
шаблоны / дома / index.html.twig
...
<form action="{{ path('login') }}" id="signInForm" role="form"method="POST" class="visible">
<h2>Sign In</h2>
<hr class="colorgraph">
<div class="form-group">
<input type="email" name="email" id="email" class="form-control input-lg" placeholder="Email Address">
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg" placeholder="Password">
</div>
<span class="button-checkbox">
<button type="button" class="btn btn-info active" data-color="info">
<i class="state-icon glyphicon glyphicon-check"></i> Remember Me</button>
<input type="checkbox" name="remember_me" id="remember_me" class="hidden">
<a href="" class="btn btn-link pull-right">Forgot Password?</a>
</span>
<hr class="colorgraph">
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<input type="submit" class="btn btn-lg btn-success btn-block" value="Sign In">
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<a id="registerBtn" href="#" class="btn btn-lg btn-block btn-toggle">To Register</a>
</div>
</div>
</form>
<form action="{{ path('register') }}" id="registerForm" role="form" method="POST">
<h2>
Please Sign Up
<small>It's free and always will be.</small>
</h2>
<hr class="colorgraph">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
<input type="text" name="first_name" id="first_name" class="form-control input-lg" placeholder="First Name" tabindex="1">
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
<input type="text" name="last_name" id="last_name" class="form-control input-lg" placeholder="Last Name" tabindex="2">
</div>
</div>
</div>
<div class="form-group">
<input type="text" name="display_name" id="display_name" class="form-control input-lg" placeholder="Display Name" tabindex="3">
</div>
<div class="form-group">
<input type="email" name="email" id="email" class="form-control input-lg" placeholder="Email Address" tabindex="4">
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg" placeholder="Password" tabindex="5">
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
<input type="password" name="password_confirmation" id="password_confirmation" class="form-control input-lg" placeholder="Confirm Password"tabindex="6">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-4 col-sm-3 col-md-3">
<span class="button-checkbox">
<button type="button" class="btn" data-color="info" tabindex="7">I Agree</button>
<input type="checkbox" name="t_and_c" id="t_and_c" class="hidden" value="1">
</span>
</div>
<div class="col-xs-8 col-sm-9 col-md-9">
By clicking
<strong class="label label-primary">Register</strong>, you agree to the
<a href="#" data-toggle="modal" data-target="#t_and_c_m">Terms and Conditions</a> set out by this site, including our Cookie Use.
</div>
</div>
<hr class="colorgraph">
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<input type="submit" value="Register" class="btn btn-primary btn-block btn-lg" tabindex="7">
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<a id="signInBtn" href="#" class="btn btn-block btn-lg btn-toggle">To Sign In</a>
</div>
</div>
</form>
...
Что должно быть в контроллере в login()
а также register()
методы?
Я читал о создании форм в Symfony, но я хочу использовать форму из представления сделано вручную.
Должно ли это выглядеть так?
public function login(Request $request) {
$email = $request->get('email');
$password = $request->get('password');
$repository = $this->getDoctrine()->getRepository(User::class);
$user = $repository->findOneBy([
'email' => $email,
'password' => $password
]);
if($user) {
// TODO: Set session
return $this->redirectToRoute('timeline');
}
return $this->redirectToRoute('home');
}
public function register(Request $request) {
$user = new User();
$firstName = $request->get('first_name');
$lastName = $request->get('last_name');
$nickname = $request->get('display_name');
$email = $request->get('email');
$password = $request->get('password');
$password2 = $request->get('password_confirmation');
// VALIDATION
return $this->render('message.html.twig', [
'header' => 'Congratulations',
'title' => 'Welcome <b>'. ucfirst($firstName) .' '. ucfirst($lastName) .'</b>!',
'message' => 'The registration process completed correctly!
An activation link has been sent to your e-mail address.',
'button' => [
'href' => $this->generateUrl('home'),
'text' => 'To Sign In'
]
]);
}
Я реализовал маленький и простой логин & сбросить действия пароля без fosuserbundle в Symfony 4. Это не так сложно сделать:
Настройте вашу безопасность:
# config/packages/security.yaml
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
our_db_provider: # Arbitrary name
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
provider: our_db_provider # Use any declared provider above
form_login:
login_path: login
check_path: login
default_target_path: /
anonymous: true
logout:
path: /logout
target: /
remember_me:
secret: '%env(APP_SECRET)%'
lifetime: 604800 # 1 week in seconds
path: /access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
Действие входа:
// src/Controller/Security/SecurityController.php
namespace App\Controller\Security;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends Controller
{
public function login(Request $request, AuthenticationUtils $authUtils)
{
$error = $authUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authUtils->getLastUsername();
return $this->render('Security/login.html.twig', [
'error' => $error,
'last_username' => $lastUsername,
]);
}
}
Шаблон входа
# templates/Security/login.html.twig
{% block body %}
<h1>Login</h1>
<div class="login-page">
<div class="form">
{% if error %}
<div class="error">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="{{ path('login') }}" method="post">
<div>
<label for="username">Email:</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" />
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="_password" />
</div>
<div class="cta">
<div>
<input type="checkbox" id="remember_me" name="_remember_me" checked />
<label for="remember_me">Keep me logged in</label>
</div>
<div>
<button type="submit">Connexion</button>
</div>
</div>
</form>
<a href="{{ path('request_password') }}">Forgot password ?</a>
</div>
</div>
{% endblock %}
Диспетчер пользователей:
# src/Manager/UserManager.php
use App\Entity\User;
use App\Util\PasswordUpdater;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* Class UserManager
* @package App\Manager
*/
class UserManager
{
/** @var EntityManagerInterface */
private $em;
/** @var PasswordUpdater */
private $passwordUpdater;
/**
* UserManager constructor.
*
* @param EntityManagerInterface $em
* @param PasswordUpdater $passwordUpdater
*/
public function __construct(EntityManagerInterface $em, PasswordUpdater $passwordUpdater)
{
$this->em = $em;
$this->passwordUpdater = $passwordUpdater;
}
/**
* Find a user by his username
*
* @param string $username
*
* @return \App\Entity\User|null
*/
public function findUserByUsername($username)
{
$user = $this->em->getRepository('App\Entity\User')->findOneBy(['username' => $username]);
return $user;
}
/**
* Update a user
*
* @param AdvancedUserInterface $user
*
* @param bool $andFlush
*/
public function updateUser(AdvancedUserInterface $user, $andFlush = true)
{
$this->em->persist($user);
if ($andFlush) {
$this->em->flush();
}
}
/**
* Find a user by his confirmationToken
*
* @param $confirmationToken
*
* @return \App\Entity\User|null
*/
public function findUserByConfirmationToken($confirmationToken)
{
$user = $this->em->getRepository('App\Entity\User')->findOneBy(['confirmationToken' => $confirmationToken]);
return $user;
}
/**
* Encode & update user password
*
* @param User $user
*/
public function updateUserPassword(User $user)
{
$this->passwordUpdater->hashPassword($user);
$user->setConfirmationToken(null);
$user->setPasswordRequestedAt(null);
}
}
И пользовательский объект:
# src/Entity/User.php
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User implements AdvancedUserInterface, \Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=25, unique=true)
*/
private $username;/**
* @ORM\Column(type="string", length=100, unique=true)
*/
private $email;
/**
* @ORM\Column(type="string", length=64)
*/
private $password;
/**
* @ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* Random string sent to the user email address in order to verify it.
*
* @var string
*
* @ORM\Column(type="string", length=180, nullable=true)
*/
protected $confirmationToken;
/**
* @var \DateTime
*
* @ORM\Column(type="datetime", nullable=true)
*/
protected $passwordRequestedAt;
/**
* User constructor.
*/
public function __construct()
{
$this->isActive = true;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
public function getUsername()
{
return $this->username;
}
public function getSalt()
{
return null;
}
public function setSalt($salt)
{
return null;
}
/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* @param mixed $email
* @return User
*/
public function setEmail($email)
{
$this->email = $email;
$this->username = $email;
return $this;
}
/**
* @return mixed
*/
public function getPassword()
{
return $this->password;
}
/**
* @param mixed $password
* @return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* @return mixed
*/
public function isActive()
{
return $this->isActive;
}
/**
* @param mixed $isActive
* @return User
*/
public function setActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function eraseCredentials()
{
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->isActive;
}
/**
* @return string
*/
public function getConfirmationToken()
{
return $this->confirmationToken;
}
/**
* @param $confirmationToken
*
* @return $this
*/
public function setConfirmationToken($confirmationToken)
{
$this->confirmationToken = $confirmationToken;
return $this;
}
/**
* @param \DateTime|null $date
*
* @return $this
*/
public function setPasswordRequestedAt(\DateTime $date = null)
{
$this->passwordRequestedAt = $date;
return $this;
}
/**
* Gets the timestamp that the user requested a password reset.
*
* @return null|\DateTime
*/
public function getPasswordRequestedAt()
{
return $this->passwordRequestedAt;
}
/**
* @param $ttl
*
* @return bool
*/
public function isPasswordRequestNonExpired($ttl)
{
return $this->getPasswordRequestedAt() instanceof \DateTime &&
$this->getPasswordRequestedAt()->getTimestamp() + $ttl > time();
}
/** @see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->username,
$this->password,
$this->isActive,
));
}
/** @see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->username,
$this->password,
$this->isActive,
) = unserialize($serialized);
}
}
Так я с этим справляюсь. Это, вероятно, не идеально, но работает нормально. Вы можете найти источники здесь: https://github.com/matthieuleorat/documentManager
Надеюсь, что это поможет вам.
контроллер входа должен быть примерно таким:
/**
* @Route("/login", name="login_route")
*/
public function loginAction()
{
$autenticacion = $this->get('security.authentication_utils');
// if there is any error, here you get it
$error = $autenticacion->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $autenticacion->getLastUsername();
return $this->render(
'login.html.twig',
array(
// last username entered by the user
'last_username' => $lastUsername,
'error' => $error,
)
);
}
И регистр делает это, сохраняя ввод в представлении, вы можете использовать Type, потому что форма нуждается в скрытых входах для безопасности.