我很可能错过了一些愚蠢的东西,但我花了很多时间在这上面,所以感谢任何帮助。
身份验证基于this tutorial
我使用bcrypt对密码进行编码,似乎在用户注册时工作正常。
但即使输入的密码正确无误,登录时也会抛出错误:
凭据无效。
我确认电子邮件和密码正确到达登录验证器(登录表单是通过Ajax提交的)。
此外,getUser()方法似乎正在从db中检索$ user对象和相应的密码。
security.yml设置如下:
security:
encoders:
UsedBundle\Entity\User:
algorithm: bcrypt
这是注册控制器:
namespace UsedBundle\Controller;
use UsedBundle\Form\UserType;
use UsedBundle\Entity\User;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use UsedBundle\Service\sendEmail;
class RegistrationController extends Controller
{
/**
* @Route("/inscription", name="inscription")
*/
public function registerAction(Request $request)
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
if ($request->isMethod('POST')) {
$form->submit($request->request->get($form->getName('user')));
if(!$form->isValid()){
// handle invalid form
}
if ($form->isSubmitted() && $form->isValid()) {
$password = $this->get('security.password_encoder')
->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
$user->setUserKey( $user->getEmail() );
$user->setUserKeyTime();
$user->setDateReg();
$em = $this->getDoctrine()->getManager('used');
$em->persist($user);
$em->flush();
return new JsonResponse(array(
'status' => 'ok',
'message' => 'Success!')
);
}
}else{
return $this->render(
'common/register.html.twig',
array('form' => $form->createView())
);
}
}
}
登录表单身份验证器(设置为服务):
namespace UsedBundle\Security;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use UsedBundle\Entity\User;
use UsedBundle\Repository\UserRepository;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
class FormLoginAuthenticator extends AbstractFormLoginAuthenticator
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getCredentials(Request $request)
{
if ($request->getPathInfo() != '/login_check') {
return;
}
$username = $request->request->get('_email');
$request->getSession()->set(Security::LAST_USERNAME, $username);
$password = $request->request->get('_password');
return array(
'username' => $username,
'password' => $password
);
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$username = $credentials['username'];
$user = $this->container
->get('doctrine')
->getRepository('UsedBundle:User', 'used')
->findOneByemail( $username );
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
$plainPassword = $credentials['password'];
$encoder = $this->container->get('security.password_encoder');
if (!$encoder->isPasswordValid($user, $plainPassword)){
throw new BadCredentialsException();
}else{
$this->pass_error = 'no error';
}
}
protected function getLoginUrl()
{
return $this->container->get('router')
->generate('homepage');
}
protected function getDefaultSuccessRedirectUrl()
{
return $this->container->get('router')
->generate('homepage');
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
// AJAX! Return some JSON
if ($request->isXmlHttpRequest()) {
return new JsonResponse(
array('userId' => $token->getUser()->getId(),
'statut' => 'ok'
)
);
}
// for non-AJAX requests, return the normal redirect
return parent::onAuthenticationSuccess($request, $token, $providerKey);
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new JsonResponse(
array('message' => $exception->getMessageKey(),
'statut' => 'error',
'passerror' => $this->pass_error )
);
}
checkCredentials()上的var_dump($ user)摘录按要求
object(UsedBundle\Entity\User)#329 (15) {
["id":"UsedBundle\Entity\User":private]=>
int(7)
["avatar":"UsedBundle\Entity\User":private]=>
string(11) "dsfdfafadfa"
["name":"UsedBundle\Entity\User":private]=>
string(9) "dfdffadfa"
["password":"UsedBundle\Entity\User":private]=>
string(64) "jjuewij/sc9Af17i+ZXAUcrdiZX83HHMLjTNVSnJ34qGCp6BAxisVtjiG3Nm+uH5"
["plainPassword":"UsedBundle\Entity\User":private]=>
NULL
["email":"UsedBundle\Entity\User":private]=>
string(22) "myemail@gmail.com"
["phone":"UsedBundle\Entity\User":private]=>
string(12) "445454545454"
["roles":"UsedBundle\Entity\User":private]=>
string(9) "ROLE_USER"
["isActive":"UsedBundle\Entity\User":private]=>
bool(true)
按要求,关于onAuthenticationFailure()的var_dump($ exception)的摘录
object(Symfony\Component\Security\Core\Exception\BadCredentialsException)#322 (8) {
["token":"Symfony\Component\Security\Core\Exception\AuthenticationException":private]=>
object(Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken)#61 (6) {
["credentials":"Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken":private]=>
array(2) {
["username"]=>
string(22) "myemail@gmail.com"
["password"]=>
string(8) "senha444"
}
["guardProviderKey":"Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken":private]=>
string(6) "main_0"
["user":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
NULL
["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) {
}
}
["message":protected]=>
string(0) ""
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(78) "/Users/BAMAC/Sites/Symfony1/src/UsedBundle/Security /FormLoginAuthenticator.php"
["line":protected]=>
int(58)
答案 0 :(得分:0)
在Edwin让我朝着正确的方向前进之后,我设法让它发挥作用。实际上,加密并不是唯一的问题。 这些更改主要涉及注册控制器,其中修改了密码加密的代码。 我还更改了表单身份验证器,现在基于this
因为我的问题上显示的先前基数已过时。
最后,Symfony与Ajax并不是很多朋友,因此Ajax URL适用于开发环境。
以下是整个代码:
security.yml
security:
encoders:
UsedBundle\Entity\User:
algorithm: bcrypt
providers:
db_provider:
entity:
class: UsedBundle:User
property: email
manager_name: used
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
provider: db_provider
form_login:
login_path: /
username_parameter: _email
check_path: /login_check
guard:
authenticators:
- app.form_login_authenticator
logout:
path: /logout
target: /
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
注册控制器的变更:
if ($form->isSubmitted() && $form->isValid()) {
$this->formData = $request->request->get($form->getName('user'));
$this->plainPassword = $this->formData['plainPassword']['first'];
$password = $this->get('security.password_encoder')
->encodePassword($user, $this->plainPassword );
.....
新身份验证员:
namespace UsedBundle\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Security;
class FormLoginAuthenticator extends AbstractGuardAuthenticator
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getCredentials(Request $request)
{
if ($request->getPathInfo() != '/login_check') {
return;
}
$email = $request->request->get('_email');
$request->getSession()->set(Security::LAST_USERNAME, $email);
$password = $request->request->get('_password');
return array(
'email' => $email,
'password' => $password
);
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$email = $credentials['email'];
return $this->user = $this->container
->get('doctrine')
->getRepository('UsedBundle:User', 'used')
->findOneByemail( $email );
}
public function checkCredentials($credentials, UserInterface $user)
{
$plainPassword = $credentials['password'];
$encoder = $this->container->get('security.password_encoder');
if (!$encoder->isPasswordValid($user, $plainPassword)){
throw new BadCredentialsException();
}else{
return true;
}
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$session=$request->getSession();
$session->set('seller_id', $token->getUser()->getId());
$session->set('email', $token->getUser()->getEmail());
return new JsonResponse(
array(
'userId' => $token->getUser()->getId(),
'message' => $this->credentials,
'statut' => 'ok',
'roles' => $token->getUser()->getRoles(),
'email' => $token->getUser()->getEmail(),
)
);
// for non-AJAX requests, return the normal redirect
//return parent::onAuthenticationSuccess($request, $token, $providerKey);
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$data = array(
'message' => strtr($exception->getMessageKey(), $exception->getMessageData())
// or to translate this message
// $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
);
return new JsonResponse($data, Response::HTTP_FORBIDDEN);
}
/**
* Called when authentication is needed, but it's not sent
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$data = array(
'message' => 'Authentication Required'
);
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
public function supportsRememberMe()
{
return false;
}
}
登录控制器:
namespace UsedBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class LoginController extends Controller
{
/**
* @Route("/login", name="login")
*/
public function loginAction(Request $request)
{
$helper = $this->get('security.authentication_utils');
return $this->render('common/login.html.twig', array(
// last username entered by the user (if any)
'last_username' => $helper->getLastUsername(),
// last authentication error (if any)
'error' => $helper->getLastAuthenticationError(),
));
}
/**
* @Route("/login_check", name="security_login_check")
*/
public function loginCheckAction()
{
// will never be executed
}
}
这就是Ajax url在开发时的样子:]
$.ajax({
url: "/app_dev.php/login_check",
type: "POST",
dataType: "json",
data: str,
success: function(data) {
.....