[英]Symfony 6 login doesn't run auth
I'm trying to make a small application in symfony 6 to practice but I can't get the login to work.我正在尝试在 symfony 6 中制作一个小型应用程序来练习,但我无法登录工作。
I have used the commands make:user
, make:crud user
, make:auth
, and I have let the application build the login for me.我使用了命令
make:user
、 make:crud user
、 make:auth
,并且我让应用程序为我构建了登录。
The thing is that I manage to register the user correctly (hashing the password) but when I try to login it only redirects me to the same page, it doesn't even show me an error message.问题是我设法正确注册了用户(散列密码),但是当我尝试登录时,它只会将我重定向到同一页面,它甚至不会向我显示错误消息。
I have noticed that when logging in the application does not send the form to App\Security\UserAuthenticator
.我注意到登录应用程序时不会将表单发送到
App\Security\UserAuthenticator
。 In previous versions of symfony the application configured all this directly for me as it should be.在以前版本的 symfony 中,应用程序直接为我配置了所有这些,因为它应该是。
This is my SecurityController
:这是我的
SecurityController
:
class SecurityController extends AbstractController { #[Route(path: '/login', name: 'app_login')] public function login(AuthenticationUtils $authenticationUtils): Response { if ($this->getUser()) { return $this->redirectToRoute('app_home'); } // get the login error if there is one $error = $authenticationUtils->getLastAuthenticationError(); // last username entered by the user $lastUsername = $authenticationUtils->getLastUsername(); return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]); } #[Route(path: '/logout', name: 'app_logout')] public function logout(): void { throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.'); } }
login.html.twig
: login.html.twig
:
{% extends 'base.html.twig' %} {% block title %}Log in.{% endblock %} {% block body %} <form method="post"> {% if error %} <div class="alert alert-danger">{{ error.messageKey|trans(error,messageData. 'security') }}</div> {% endif %} {% if app.user %} <div class="mb-3"> You are logged in as {{ app.user,userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a> </div> {% endif %} <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1> <label for="inputUsername">Username</label> <input type="text" value="{{ last_username }}" name="username" id="inputUsername" class="form-control" autocomplete="username" required autofocus> <label for="inputPassword">Password</label> <input type="password" name="password" id="inputPassword" class="form-control" autocomplete="current-password" required> <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}" > <button class="btn btn-lg btn-primary" type="submit"> Sign in </button> </form> {% endblock %}
UserAuthenticator
: UserAuthenticator
:
class UserAuthenticator extends AbstractLoginFormAuthenticator { use TargetPathTrait; public const LOGIN_ROUTE = 'app_login'; private UrlGeneratorInterface $urlGenerator; public function __construct(UrlGeneratorInterface $urlGenerator) { $this->urlGenerator = $urlGenerator; } public function authenticate(Request $request): Passport { $username = $request->request->get('username', ''); $request->getSession()->set(Security::LAST_USERNAME, $username); return new Passport( new UserBadge($username), new PasswordCredentials($request->request->get('password', '')), [ new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')), ] ); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) { return new RedirectResponse($targetPath); } // For example: return new RedirectResponse($this->urlGenerator->generate('app_home')); } protected function getLoginUrl(Request $request): string { return $this->urlGenerator->generate(self::LOGIN_ROUTE); } }
security.yaml
: security.yaml
:
security: # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords password_hashers: Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider providers: # used to reload user from session & other features (eg switch_user) app_user_provider: entity: class: App\Entity\User property: username firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: lazy: true provider: app_user_provider custom_authenticator: App\Security\UserAuthenticator logout: path: app_logout # where to redirect after logout # target: app_any_route # activate different ways to authenticate # https://symfony.com/doc/current/security.html#the-firewall # https://symfony.com/doc/current/security/impersonating_user.html # switch_user: true # Easy way to control access for large sections of your site # Note: Only the *first* access control that matches will be used access_control: # - { path: ^/admin, roles: ROLE_ADMIN } # - { path: ^/profile, roles: ROLE_USER } when@test: security: password_hashers: # By default, password hashers are resource intensive and take time. This is # important to generate secure password hashes. In tests however, secure hashes # are not important, waste resources and increase test times. The following # reduces the work factor to the lowest possible values. Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: algorithm: auto cost: 4 # Lowest possible value for bcrypt time_cost: 3 # Lowest possible value for argon memory_cost: 10 # Lowest possible value for argon
I hope you can give me a hand, I don't understand what is happening and some things that I have read while googling have not helped me.我希望你能帮帮我,我不明白发生了什么,我在谷歌搜索时读到的一些东西对我没有帮助。 Thanks.
谢谢。
I had the same problem as you.我和你有同样的问题。 I followed the tutorial https://symfony.com/doc/current/security.html but my connection was not working.
我按照教程https://symfony.com/doc/current/security.html但我的连接不起作用。
I then did a $symfony make:auth然后我做了一个 $symfony make:auth
Choose [1]Login form authenticator选择[1]登录表单验证器
My config/packages/security.yaml我的 config/packages/security.yaml
security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
secured_area:
# form_login:
# enable_csrf: true
custom_authenticator: App\Security\UserAuthenticator
logout:
path: app_logout
# where to redirect after logout
# target: app_any_route
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
form_login:
login_path: login
check_path: login
default_target_path: home
logout:
path: app_logout
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
when@test:
security:
password_hashers:
# By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon
I have change /login to /connexion in my SecurityController:我在 SecurityController 中将 /login 更改为 /connexion:
#[Route(path: '/connexion', name: 'app_login')]
public function login(AuthenticationUtils $authenticationUtils): Response
{
Now it works for me.现在它对我有用。
main:
pattern: ^/
user_checker: App\Security\UserChecker
lazy: true
form_login:
# "login" is the name of the route created previously
login_path: app_login
check_path: app_login
here the full procedure to create users and login:这里是创建用户和登录的完整过程:
Symfony 6.1 Symfony 6.1
$ php bin/console make:user
$ php bin/console make:migration
$ php bin/console doctrine:migrations:migrate
Create a temp user to test (crypted password is 'test')创建一个临时用户进行测试(加密密码为“test”)
INSERT INTO `user` (`id`, `email`, `roles`, `password`) VALUES (1, 'johndoe@site.com', '["ROLE_ADMIN"]', '$2y$13$zMYKGkggUiUdAGedrgpXF.jlArzta9k3UgBCKEvoF1ILsbbSxx8by');
Create the Login Form创建登录表单
$ php bin/console make:controller Login
Security Config安全配置
# config/packages/security.yaml
security:
# ...
firewalls:
main:
# ...
form_login:
# "app_login" is the name of the route created previously
login_path: app_login
check_path: app_login
logout:
path: app_logout
Logout route登出路线
# api/config/routes.yaml
# ...
app_logout:
path: /logout
methods: GET
# ...
CSFR Protection CSFR 保护
# config/packages/security.yaml
security:
# ...
firewalls:
secured_area:
# ...
form_login:
# ...
enable_csrf: true
# config/packages/framework.yaml
framework:
# ...
csrf_protection: ~
LoginController登录控制器
// src/Controller/LoginController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class LoginController extends AbstractController
{
#[Route('/login', name: 'app_login')]
public function index(AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('login/index.html.twig', [
'controller_name' => 'LoginController',
'last_username' => $lastUsername,
'error' => $error
]);
}
}
Login Template登录模板
{# templates/login/index.html.twig #}
{% extends 'base.html.twig' %}
{# ... #}
{% block body %}
{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="{{ path('app_login') }}" method="post">
<label for="username">Email:</label>
<input type="text" id="username" name="_username" value="{{ last_username }}"/>
<label for="password">Password:</label>
<input type="password" id="password" name="_password"/>
{# If you want to control the URL the user is redirected to on success
<input type="hidden" name="_target_path" value="/api"/> #}
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<button type="submit">login</button>
</form>
{% endblock %}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.