2015-07-17 3 views
1

У меня есть веб-приложение SPA, которое использует интерфейс AngularJS для интерфейса и Symfony2 для бэкэнд.Регистрация FOSUserBundle в AngularJS

Я использовал FOSUserBundle для обработки User.

То, что я хочу сделать прямо сейчас, чтобы использовать AngularJS метод регистрации мой User, который через Ajax

Моя проблема заключается в том, что всякий раз, когда я отправить форму, он печатает в журнале консоли "invalid form".

Вот мой текущий прогресс:

new.html

<form class="form-group text-left" ng-submit="submit()" novalidate name="userFrm"> 
    <div class="form-group"> 
     <label for="user.email" class="required">Email</label> 
     <input id="user.email" name="user.email" class="form-control" type="text" ng-model="user.email" /> 
    </div> 
    <div class="form-group"> 
     <label for="user.username" class="required">Username</label> 
     <input id="user.username" name="user.username" class="form-control" type="text" ng-model="user.username" /> 
    </div> 
    <div class="form-group"> 
     <label for="user.plainPassword" class="required">Password</label> 
     <input id="user.plainPassword" name="user.plainPassword" class="form-control" type="password" ng-model="user.plainPassword" /> 
    </div> 
    <div class="form-group"> 
     <label for="confirmPassword" class="required">Confirm Password</label> 
     <input id="confirmPassword" name="confirmPassword" compare-to="user.plainPassword" class="form-control" type="password" ng-model="confirmPassword" /> 
    </div> 
    <input type="submit" value="Register" ng-disabled="userFrm.$invalid" class="btn btn-primary center-block col-lg-2" /> 
</form> 

new.js

'use strict'; 

(function() { 
    angular.module('myApp.user.new', []) 
     .config(['$stateProvider', function ($stateProvider) { 
       $stateProvider 
         .state('user.new', { 
          url: "/new", 
          controller: "NewUserCtrl", 
          templateUrl: PATH + 'user/new/new.html' 
         }); 
      }]) 

     .controller('NewUserCtrl', ["$scope", "$http", "$state", function ($scope, $http, $state) { 

       var success = function (response) { 
        var valid = response.data.valid; 
        if (valid) { 
         $state.go('home'); 
        } else { 
         console.log("invalid form"); 
        } 
       }; 

       var error = function (reason) { 
        console.log("Submission failed"); 
       }; 

       $scope.submit = function() { 
        var formData = { 
         fos_user_registration: $scope.user, 
         confirmPass: $scope.confirmPassword 
        }; 

        $http.post(Routing.generate('fos_user_registration_register'), $.param(formData), { 
         headers: {'Content-Type': 'application/x-www-form- urlencoded'} 
        }) 
          .then(success, error); 
       }; 
      }]); 

}()); 

RegistrationController.php (переопределен из FOSUserBundle)

public function registerAction(Request $request) { 
    /** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */ 
    $formFactory = $this->get('fos_user.registration.form.factory'); 
    /** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */ 
    $userManager = $this->get('fos_user.user_manager'); 

    $user = $userManager->createUser(); 
    $user->setEnabled(true); 

    $form = $formFactory->createForm(); 
    $form->setData($user); 

    $form->handleRequest($request); 

    if ($form->isValid()) { 
     $user->addRole('ROLE_ADMIN'); 
     $userManager->updateUser($user); 

     $response = ['valid' => true]; 
     return new JsonResponse($response); 
    } 


    $response = ['valid' => false]; 
    return new JsonResponse($response); 
} 

ответ

1

Я не вижу токен CSRF в вашей форме. Ваша форма не может быть проверена без токена CSRF. Сначала проверьте здесь; http://symfony.com/doc/current/cookbook/security/csrf_in_login_form.html

Также может быть лучше сгенерировать ваши формы с помощью шаблона для завивки волос для полной совместимости. Глянь сюда; http://symfony.com/doc/current/book/forms.html

Для дальнейшего расследования, почему ваша форма не подтверждена, вы можете написать блок else для проверки $form->isValid() и использовать метод в ответе, чтобы увидеть ошибки в вашей форме. Вы можете проверить, почему ваша форма не проверяется. https://stackoverflow.com/a/17428869/3399234

UPDATE

Я придумал решение. Я использовал конфигурацию Vagrant, которая включает symfony 2.6.10. Я переопределил RegistrationFormType, поместил его в свой собственный пакет и ввел его как услугу, как и FOS. Я заменил регистрационную форму FOS своим собственным служебным псевдонимом. Поэтому мне удалось отключить защиту csrf в моем overrideen RegistrationFormType.

Также добавлен для установки модели plainPassword для пользователя, чтобы исправить ошибку сохранения в USerManager.

Контроллер, переопределяет контроллер регистрации FOS.

<?php 

namespace Acme\WebBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use FOS\UserBundle\Controller\RegistrationController as BaseController; 
use Symfony\Component\HttpFoundation\Request as Request; 
use Symfony\Component\HttpFoundation\JsonResponse as JsonResponse; 

class RegistrationController extends BaseController 
{ 
    public function registerAction() 
     { 

      $request = Request::createFromGlobals(); 

      $form = $this->container->get('fos_user.registration.form'); 
      /** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */ 
      $userManager = $this->container->get('fos_user.user_manager'); 

      $user = $userManager->createUser(); 
      $form->setData($user); 

      $form->handleRequest($request); 

      if ($form->isValid()) {    
       $user->setEnabled(true); 
       $user->addRole('ROLE_ADMIN'); 
       $userManager->updateUser($user); 

       $response = ['valid' => true]; 
       return new JsonResponse($response); 
      } else { 
       $string = (string) $form->getErrors(true, false); 
       //Show errors 
       $response = ['valid' => false]; 
       return new JsonResponse($response); 

      } 
      return $this->container->get('templating')->renderResponse('AcmeWebBundle:Default:index.html.twig'); 
     } 

} 

перекрываться ФОС Регистрационная форма,

<?php 
//Acme\WebBundle\Form\Type\RegistrationFormType.php 
namespace Acme\WebBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class RegistrationFormType extends AbstractType 
{ 

    private $class; 

    /** 
    * @param string $class The User class name 
    */ 
    public function __construct($class) 
    { 
     $this->class = $class; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => $this->class, 
      'intention' => 'registration', 
      'csrf_protection' => false, //this line does the trick ;) 
     )); 
    } 

    public function getParent() 
    { 
     return 'fos_user_registration'; 
    } 

    public function getName() 
    { 
     return 'acme_user_registration'; 
    } 
} 

Services.yml

services: 
    acme.registration.form.type: 
     class: Acme\WebBundle\Form\Type\RegistrationFormType 
     arguments: ["%fos_user.model.user.class%"] 
     tags: 
      - { name: form.type, alias: acme_user_registration } 

index.html.twig

 <script type="text/javascript"> 

         var app = angular.module('myApp', []); 

          app.controller('NewUserCtrl', ["$scope", "$http", function ($scope, $http) { 

            var success = function (response) { 
             var valid = response.data.valid; 
             if (valid) { 
              $state.go('home'); 
             } else { 
              console.log("invalid form"); 
             } 
            }; 

            var error = function (reason) { 
             console.log("Submission failed"); 
            }; 

            $scope.submit = function() { 
             var formData = { 
              fos_user_registration_form: $scope.user 
             }; 

            $http.post('<YOUR URL HERE>', $.param(formData), { 
              headers: {'Content-Type': 'application/x-www-form-urlencoded'} 
             }).then(success, error); 
            }; 
           }]); 
       </script> 

<div id="content" ng-app="myApp" ng-controller="NewUserCtrl" > 

    <form class="form-group text-left" ng-submit="submit()" novalidate name="userFrm"> 
     <div class="form-group"> 
      <label for="user.email" class="required">Email</label> 
      <input id="user.email" name="user.email" class="form-control" type="text" ng-model="user.email" /> 
     </div> 
     <div class="form-group"> 
      <label for="user.username" class="required">Username</label> 
      <input id="user.username" name="user.username" class="form-control" type="text" ng-model="user.username" /> 
     </div> 
     <div class="form-group"> 
      <label for="user.plainPassword.first" class="required">Password</label> 
      <input id="user.plainPassword.first" name="user.plainPassword.first" class="form-control" type="password" ng-model="user.plainPassword.first" /> 
     </div> 
     <div class="form-group"> 
      <label for="user.plainPassword.second" class="required">Confirm Password</label> 
      <input id="user.plainPassword.second" name="user.plainPassword.second" compare-to="user.plainPassword.first" class="form-control" type="password" ng-model="user.plainPassword.second" /> 
     </div> 
     <input type="submit" value="Register" ng-disabled="userFrm.$invalid" class="btn btn-primary center-block col-lg-2" /> 
    </form> 
</div> 

Это конфигурация fos_user в конфигурации.yml, чтобы изменить форму по умолчанию с вашей переопределенной формой при вызове регистрационной формы FOS User bundle.

config.yml

fos_user: 
    registration: 
     form: 
      type: acme_user_registration 

И вот это я могу отправить с формой и сохраняются пользователя к базе данных, то вернуть {"valid":true} ответ, как и ожидалось. И, наконец, у меня есть шанс научиться вводить AngularJS в Symfony 2, радует это.

+0

Комментарии не предназначены для расширенного обсуждения; этот разговор был [перемещен в чат] (http://chat.stackoverflow.com/rooms/83589/discussion-on-answer-by-ugur-fosuserbundle-register-in-angularjs). – Taryn

+0

Он продолжает бросать внутреннюю ошибку сервера. Я попытался сделать службу в формате xml. Я также обновил до 2.6. Все еще не работает. – schizoskmrkxx

+0

Наконец-то он работал. Кажется, я упустил часть $ plainPass в контроллере. Я также улучшил его и удалил часть $ plainPass. Теперь он автоматически привязывается к форме и удаляет ошибку сохранения. Проверьте мои изменения. – schizoskmrkxx

Смежные вопросы