Symfony 3 无法使用 ajax 登录
Posted
技术标签:
【中文标题】Symfony 3 无法使用 ajax 登录【英文标题】:Symfony 3 unable to login with ajax 【发布时间】:2017-12-06 16:41:14 【问题描述】:首先,我没有在这个项目中使用 FOSUserBundle。所以,让我们把它排除在外。
我可以注册用户,但无法登录。
我验证了表单已发布到 LoginController 并且它生成了 authenticationUtils 对象,但它没有生成错误,即使下面有一个错误:
$error = $authUtils->getLastAuthenticationError();
否则不会产生任何错误。它默默地失败了。即使我提供了正确的凭据,_wdt 仍会继续显示为匿名。
security.yml
security:
encoders:
UsedBundle\Entity\User:
algorithm: bcrypt
providers:
db_provider:
entity:
class: UsedBundle:User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
provider: db_provider
form_login:
username_parameter: _email
登录控制器: UsedBundle\Controller\LoginController
namespace UsedBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
class LoginController extends Controller
/**
* @Route("/login", name="login")
*/
public function loginAction(Request $request)
if ($request->isMethod('POST'))
var_dump($_POST);
$authUtils = $this->get('security.authentication_utils');
// get the login error if there is one
$error = $authUtils->getLastAuthenticationError();
var_dump($error);
var_dump($authUtils);
if(isset($error))
$message = $error->getMessageData();
var_dump($message);
// last username entered by the user
$lastUsername= $authUtils->getLastUsername();
return new JsonResponse(array(
'last_username' => $lastUsername,
'error' => $error,)
);
else
return $this->render('common/login.html.twig');
表单模板:
app\Resources\Views\Common\login.html.twig
% if error is defined and error is not null %
dump(error)
<div> error.messageKey|trans(error.messageData, 'security') </div>
% else %
<form action="" method="post" name="login_form" id="login_form" >
<div class="contact" >
<input type="email" id="email" name="_email" class="form-control" placeholder="e-mail" value=" % if last_username is defined %
last_username
% endif %
" />
</div>
<div class="contact" >
<input type="password" id="password" name="_password" placeholder="mot de passe" />
</div>
<div>
<button type="submit" class="sub_ok btn btn-sm" name="submit" >Valider</button>
</div>
</form>
% endif %
User 实体设置了 getUsername() 方法来返回电子邮件:
namespace UsedBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Table(name="users")
* @ORM\Entity(repositoryClass="UsedBundle\Repository\UserRepository")
* @UniqueEntity(fields="email", message="Email already taken")
* @UniqueEntity(fields="avatar", message="Username already taken")
*/
class User implements UserInterface, \Serializable
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=50, unique=true)
* @Assert\Regex(
* pattern="/^[A-Za-z0-9\s_\-.]5,50$/",
* message="Minimum 5 caracteres, max 50."
* )
*/
private $avatar;
/**
* @ORM\Column(type="string", length=50)
* @Assert\Regex(
* pattern="/^[a-zA-Z\s]5,50$/",
* message="Minimum 5 lettres, max 50."
* )
*/
private $name;
/**
* @ORM\Column(type="string", length=64)
*/
private $password;
/**
* @Assert\Length(max=4096)
* @Assert\Regex(
* pattern="/^.8,50$/",
* message="Minimum 8 caracteres, max 50."
* )
*/
private $plainPassword;
/**
* @ORM\Column(type="string", length=100, unique=true)
* @Assert\NotBlank()
* @Assert\Email()
*/
private $email;
/**
* @ORM\Column(type="string", length=50)
* @Assert\Regex(
* pattern="/^[0-9]10,20$/",
* message="Minimum 5 lettres, max 50."
* )
*/
private $phone;
/**
* @ORM\Column(type="string", length=50)
*/
private $role;
/**
* @ORM\Column(type="boolean")
*/
private $isActive;
/**
* @ORM\Column(type="string", length=64)
*/
private $userKey;
/**
* @ORM\Column(type="datetime")
* @Assert\DateTime()
*/
private $userKeyTime;
/**
* @ORM\Column(type="datetime")
* @Assert\DateTime()
*/
private $dateReg;
/**
* @ORM\Column(type="string", length=10)
*/
private $blogSubs;
/**
* Many users for one city
* @ORM\ManyToOne(targetEntity="City",inversedBy="users")
* @ORM\JoinColumn(name="city_id", referencedColumnName="id")
*/
private $cityId;
/**
* one visitor may correspond to one user
*
* @ORM\OneToOne(targetEntity="Visitor", mappedBy="userId")
*/
private $visitor;
public function __construct()
$this->isActive = false;
$this->role = 'ROLE_USER';
//$this->blogSubs = 0;
public function getUsername()
return $this->email;
public function getSalt()
return null;
public function getPassword()
return $this->password;
public function getRoles()
return array('ROLE_USER');
public function eraseCredentials()
/** @see \Serializable::serialize() */
public function serialize()
return serialize(array(
$this->id,
$this->username,
$this->password,
// $this->salt,
));
/** @see \Serializable::unserialize() */
public function unserialize($serialized)
list (
$this->id,
$this->username,
$this->password,
// $this->salt
) = unserialize($serialized);
/**
* Get id
*
* @return integer
*/
public function getId()
return $this->id;
/**
* Set avatar
*
* @param string $avatar
*
* @return User
*/
public function setAvatar($avatar)
$this->avatar = $avatar;
return $this;
/**
* Get avatar
*
* @return string
*/
public function getAvatar()
return $this->avatar;
/**
* Set name
*
* @param string $name
*
* @return User
*/
public function setName($name)
$this->name = $name;
return $this;
/**
* Get name
*
* @return string
*/
public function getName()
return $this->name;
/**
* Set password
*
* @param string $password
*
* @return User
*/
public function setPassword($password)
$this->password = $password;
return $this;
/**
* Set email
*
* @param string $email
*
* @return User
*/
public function setEmail($email)
$this->email = $email;
return $this;
/**
* Get email
*
* @return string
*/
public function getEmail()
return $this->email;
/**
* Set phone
*
* @param string $phone
*
* @return User
*/
public function setPhone($phone)
$this->phone = $phone;
return $this;
/**
* Get phone
*
* @return string
*/
public function getPhone()
return $this->phone;
/**
* Set isActive
*
* @param boolean $isActive
*
* @return User
*/
public function setIsActive($isActive)
$this->isActive = $isActive;
return $this;
/**
* Get isActive
*
* @return boolean
*/
public function getIsActive()
return $this->isActive;
/**
* Set userKey
*
* @param string $email
*
* @return User
*/
public function setUserKey( $email )
$cur_time = time();
$this->userKey = password_hash($email.$cur_time, PASSWORD_BCRYPT )."\n";
return $this;
/**
* Get userKey
*
* @return string
*/
public function getUserKey()
return $this->userKey;
/**
* Set userKeyTime
*
*
* @return User
*/
public function setUserKeyTime( $hours_added = null )
if ( $hours_added === null )
$hours_added = 20;
$literal_time = \DateTime::createFromFormat('Y-m-d H:i:s',date("Y-m-d H:i:s", strtotime('+' . $hours_added . ' hours')));
else
$literal_time = \DateTime::createFromFormat('Y-m-d H:i:s',date("Y-m-d H:i:s", time()));
$this->userKeyTime = $literal_time;
return $this;
/**
* Get userKeyTime
*
* @return \DateTime
*/
public function getUserKeyTime()
return $this->userKeyTime;
/**
* Get dateReg
*
* @return \DateTime
*/
public function getDateReg()
return $this->dateReg;
/**
* Set dateReg
*
* @return \DateTime
*/
public function setDateReg()
$literal_time = \DateTime::createFromFormat('Y-m-d H:i:s',date("Y-m-d H:i:s"));
$this->dateReg = $literal_time;
return $this;
/**
* Set role
*
* @param string $role
*
* @return User
*/
public function setRole($role)
$this->role = $role;
return $this;
/**
* Get role
*
* @return string
*/
public function getRole()
return $this->role;
/**
* Set blogSubs
*
* @param string $blogSubs
*
* @return User
*/
public function setBlogSubs($blogSubs)
$this->blogSubs = $blogSubs;
return $this;
/**
* Get blogSubs
*
* @return string
*/
public function getBlogSubs()
return $this->blogSubs;
/**
* Get plainPassword
*
* @return string
*/
public function getPlainPassword()
return $this->plainPassword;
/**
* Set cityId
*
* @param \UsedBundle\Entity\City $cityId
*
* @return User
*/
public function setCityId(\UsedBundle\Entity\City $cityId = null)
$this->cityId = $cityId;
return $this;
/**
* Get cityId
*
* @return \UsedBundle\Entity\City
*/
public function getCityId()
return $this->cityId;
/**
* Set models
*
* @param \UsedBundle\Entity\Visitor $models
*
* @return User
*/
public function setModels(\UsedBundle\Entity\Visitor $models = null)
$this->models = $models;
return $this;
/**
* Get models
*
* @return \UsedBundle\Entity\Visitor
*/
public function getModels()
return $this->models;
/**
* Set visitor
*
* @param \UsedBundle\Entity\Visitor $visitor
*
* @return User
*/
public function setVisitor(\UsedBundle\Entity\Visitor $visitor = null)
$this->visitor = $visitor;
return $this;
/**
* Get visitor
*
* @return \UsedBundle\Entity\Visitor
*/
public function getVisitor()
return $this->visitor;
表单通过ajax提交,如下:
$(document).ready(function()
$('#login_form').submit(function(e)
var str = $("#login_form").serialize();
$.ajax(
url: "/login",
type: "POST",
dataType: "json",
data: str,
success: function(data)
alert(data);
e.preventDefault(); //STOP default action
);
);
);
我正在从 Firebug 添加下面的输出。我不确定它是如何产生的,但它显示角色属性为空。仍然不确定为什么。所有用户在数据库上都有 ROLE_USER
object(Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken)#2384 (6)
["credentials":"Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken":private]=>
string(8) "senha444"
["providerKey":"Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken":private]=>
string(4) "main"
["user":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
string(22) "myemail@gmail.com"
["roles":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
array(0)
["authenticated":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
bool(false)
["attributes":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
array(0)
【问题讨论】:
我最近添加了一个类似的问题,问题是我试图不使用 HTTPS 登录,而在 config.yml framework.session.cookie_secure 中是真的。所以应用程序无法创建 cookie。不知道是不是同一个问题,但我无法登录,我没有错误。 感谢@Picoss,我在 config.yml 上根本没有设置该参数。我确实检查了 /web 目录上的 php.ini,它没有关于它的指令,并且 MAMP 的 php 信息 session.cookie_secure 和 session.cookie_httponly 已关闭。 嗯,我认为您发送 POST 的 url 不正确。您不应该在 /login 上提交表单,而是在 /login_check 上提交。或者,如果您想在 /login 上发布登录表单,请添加您的防火墙配置 login_path 和 check_path。查看有关“如何构建传统登录表单”的 Symfony2 文档:symfony.com/doc/current/security/form_login_setup.html @Picoss,我认为在这种情况下没有必要。 Ajax 将路由路由到正确的控制器。设置是这样的,每个页面都有一个登录表单。如果我把它放在上面,它就会无缘无故地开始重定向。 @BernardA 当您检查分析器时,您可以检查对/login_check
URL 的请求吗?您可以使用分析器中的“最后 10 个”按钮检查上一个请求。我还建议您使用debug component,它为您提供dump
功能,而不是var_dump
?
【参考方案1】:
这不会像上面的设置那样工作。 Symfony 不能很好地与 Ajax 配合使用,因此需要自定义登录。
我已经在this question 上添加了整个设置的答案。
【讨论】:
以上是关于Symfony 3 无法使用 ajax 登录的主要内容,如果未能解决你的问题,请参考以下文章
Symfony2:使用两个不同的用户提供程序登录网站时无法模拟用户
使用Symfony框架在生产服务器上登录失败(由于...无法处理身份验证请求)
使用 Symfony 框架在生产服务器上的用户登录失败(身份验证请求无法处理,因为...)