墨香年少 32 发布于 2023年12月3日 twig: {# templates/login/index.html.twig #} {% extends 'base.html.twig' %} {% block body %} {% if is_granted('IS_AUTHENTICATED') %} <p>username: {{ app.user.username }}, <a href="{{ path('app_logout') }}">exit</a></p> {% else %} not logined {% endif %} <hr /> <script src="/js/jquery-3.7.1.min.js"></script> <form id="form"> <label for="username">Email:</label> <input type="text" id="username" name="username" value=""> <br /> <label for="password">Password:</label> <input type="password" id="password" name="password"> <br /> <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}" style="width:100%" /> <br /> <button type="button" id="btn_login">login</button> </form> <script> var api = "{{ path('app_login') }}"; function ajax(url,data,callbak){ $.ajax({ type: "POST", url: url, data: data, dataType: 'json', success: callbak, error: function (XMLHttpRequest, textStatus, errorThrown) {alert("Ajax error.");} }); } $(document).ready(function(){ $('#btn_login').click(function(){ ajax(api,$('#form').serialize(),function(json){ console.info(json) }); }); }); </script> {% endblock %} controller: <?php //src/Controller/LoginController.php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use App\Entity\User; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; class LoginController extends AbstractController { private UserPasswordHasherInterface $passwordHasher; private EntityManagerInterface $entityManager; private TokenStorageInterface $tokenStorage; private EventDispatcherInterface $eventDispatcher; public function __construct( UserPasswordHasherInterface $_passwordHasher, EntityManagerInterface $_entityManager, TokenStorageInterface $_tokenStorage, EventDispatcherInterface $_eventDispatcher ) { $this->passwordHasher = $_passwordHasher; $this->entityManager = $_entityManager; $this->tokenStorage = $_tokenStorage; $this->eventDispatcher = $_eventDispatcher; } #[Route('/login', name: 'app_login')] public function index(Request $request,Security $security): Response { if($request->isXmlHttpRequest()) { $username = $request->request->get('username',''); $password = $request->request->get('password',''); $csrf_token = $request->request->get('_csrf_token',''); if (!$this->isCsrfTokenValid('authenticate', $csrf_token)) { return new Response('invalidate authenticate csrf_token'); } $user = $this->entityManager->getRepository(\App\Entity\User::class)->findOneBy(['username'=>$username]); if(!$user) { return new Response('user not exists'); } if($this->passwordHasher->isPasswordValid($user,$password)) { $token = new UsernamePasswordToken($user, 'main', $user->getRoles()); $this->tokenStorage->setToken($token); $event = new \Symfony\Component\Security\Http\Event\InteractiveLoginEvent($request, $token); $this->eventDispatcher->dispatch($event); $security->login($user, 'json_login', 'main', [(new RememberMeBadge())->enable()]); return new Response('OK'); }else { return new Response('passwd error!'); } } else { return $this->render('login/index.html.twig'); } } #[Route('/logout', name: 'app_logout', methods: ['GET'])] public function logout(Security $security): Response { // logout the user in on the current firewall $response = $security->logout(); // you can also disable the csrf logout $response = $security->logout(false); // ... return $response (if set) or e.g. redirect to the homepage } } 这样就可以实现自动登录了 目之所及,皆是回忆,心之所想,皆是过往 分享这篇帖子 链接帖子 分享到其他站点
墨香年少 32 发布于 2023年12月3日 配置文件: security: # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords password_hashers: App\Entity\User: # the new hasher, along with its options algorithm: sodium migrate_from: - bcrypt # uses the "bcrypt" hasher with the default options - legacy # uses the "legacy" hasher configured above Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: algorithm: sodium cost: 15 # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider providers: 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 entry_point: App\Security\AuthenticationEntryPoint logout: path: app_logout #form_login: # login_path: app_login # check_path: app_login json_login: check_path: app_login username_path: security.credentials.login password_path: security.credentials.password remember_me: secret: '%kernel.secret%' # required lifetime: 86400 always_remember_me: true access_control: - { path: /login, role: PUBLIC_ACCESS } - { path: ^/, 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 目之所及,皆是回忆,心之所想,皆是过往 分享这篇帖子 链接帖子 分享到其他站点