2014-12-27 18 views
6

Ich versuche, FOSUserBundle und HWIOAuthBundle folgende Artikel wie https://gist.github.com/danvbe/4476697 zu kombinieren. Ich möchte jedoch nicht die automatische Registrierung von OAuth2 authentifizierten neuen Benutzern: zusätzliche Informationen sollten vom Benutzer zur Verfügung gestellt werden.FOSUserBundle und HWIOAuthBundle Registrierung

Wunschergebnis

würde ich zum Beispiel möchte, dass die folgenden Informationen für eine registrierte Benutzer:

  • (Benutzername, obwohl ich eher E-Mail verwenden, nur würde)
  • Anzeigename (erforderlich)
  • Profilbild (erforderlich)
  • E-Mail-Adresse (erforderlich, wenn keine Facebook-ID)
  • Passwort (erforderlich, wenn keine Facebook-ID)
  • Facebook-ID (wenn keine E-Mail-Adresse erforderlich)

Wenn nun ein Benutzer über Facebook authentifiziert und der Benutzer gibt es noch nicht, ich habe eine Registrierung mag Formular zum Ausfüllen der fehlenden Informationen (Anzeigename und Profilbild). Erst danach sollte der neue FOSUser erstellt werden. In den meisten Tutorials werden Felder wie Profilbild und E-Mail-Adresse automatisch mit den Facebook-Informationen ausgefüllt. Dies ist nicht immer wünschenswert oder möglich.

Denken Sie auch an Dinge wie das Akzeptieren von Vertragsbedingungen und Regeln, die Sie anzeigen möchten, bevor der Benutzer erstellt wird.

Mögliche Ansätze

Eine Lösung wäre, glaube ich, eine neue Art-of AnonymousToken zu schaffen, die OAuthenticatedToken, die die relevanten Informationen OAuth2 hält jedoch keine Authenticaton zählen. Stellen Sie dann alle Seiten auf diese Art der Authentifizierung ein und lassen Sie andere Seiten zur OAuth-Registrierungsseite umleiten. Dies scheint mir jedoch eine unnötig komplizierte Lösung zu sein.

Eine andere Lösung wäre wahrscheinlich, den Code von Grund auf neu zu schreiben und nicht die beiden erwähnten Bündel zu verwenden. Ich hoffe wirklich, dass das nicht notwendig ist.

F: Wie kann ich den Registrierungsabschlusscode in den Rest des Login-Ablaufs einfügen?

(ich würde gerne einige Codes teilen, aber da es das Konzept ist auf Ich brauche Hilfe, ich habe nicht viel zu zeigen.

)

Edit: Lösung

Nach Derick der adivce, bekam ich die Grundlagen wie diese Arbeit:

Der Benutzer Provider Benutzerdefinierte speichert die Informationen (leider keinen Zugriff auf die rohen Token so kann ich noch nicht Melden Sie den Benutzer nach der Registrierung in):

class UserProvider extends FOSUBUserProvider { 

    protected $session; 

    public function __construct(Session $session, UserManagerInterface $userManager, array $properties) { 
     $this->session = $session; 
     parent::__construct($userManager, $properties); 
    } 

    public function loadUserByOAuthUserResponse(UserResponseInterface $response) 
    { 
     try { 
      return parent::loadUserByOAuthUserResponse($response); 
     } 
     catch (AccountNotLinkedException $e) { 
      $this->session->set('oauth.resource', $response->getResourceOwner()->getName()); 
      $this->session->set('oauth.id', $response->getResponse()['id']); 
      throw $e; 
     } 
    } 

} 

Individuelle Ausfall-Handler:

<?php 
// OAuthFailureHandler.php 
class OAuthFailureHandler implements AuthenticationFailureHandlerInterface { 

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { 

     if (!$exception instanceof AccountNotLinkedException) { 
      throw $exception; 
     } 

     return new RedirectResponse('fb-register'); 

    } 

} 

Beide sind als Dienst registriert:

# services.yml 
services: 
    app.userprovider: 
     class: AppBundle\Security\Core\User\UserProvider 
     arguments: [ "@session", "@fos_user.user_manager", {facebook: facebookID} ] 
    app.oauthfailurehandler: 
     class: AppBundle\Security\Handler\OAuthFailureHandler 
     arguments: ["@security.http_utils", {}, "@service_container"] 

Und in Sicherheit Config konfiguriert:

# security.yml 
security: 
    providers: 
     fos_userbundle: 
      id: fos_user.user_provider.username_email 
    firewalls: 
     main: 
      form_login: 
       provider:   fos_userbundle 
       csrf_provider:  form.csrf_provider 
       login_path:   /login 
       check_path:   /login_check 
       default_target_path: /profile 
      oauth: 
       login_path:   /login 
       check_path:   /login_check 
       resource_owners: 
        facebook:  hwi_facebook_login 
       oauth_user_provider: 
        service:   app.userprovider 
       failure_handler:  app.oauthfailurehandler 
      anonymous: true 
      logout: 
       path:   /logout 
       target:   /login 

An/fb-Register, lasse ich der Benutzer einen Benutzernamen eingeben und den Benutzer selbst sparen:

/** 
* @Route("/fb-register", name="hwi_oauth_register") 
*/ 
public function registerOAuthAction(Request $request) { 

    $session = $request->getSession(); 

    $resource = $session->get('oauth.resource'); 
    if ($resource !== 'facebook') { 
     return $this->redirectToRoute('home'); 
    } 

    $userManager = $this->get('fos_user.user_manager'); 
    $newUser = $userManager->createUser(); 

    $form = $this->createForm(new RegisterOAuthFormType(), $newUser); 
    $form->handleRequest($request); 

    if ($form->isValid()) { 

     $newUser->setFacebookId($session->get('oauth.id')); 
     $newUser->setEnabled(true); 

     $userManager->updateUser($newUser); 

     try { 
      $this->container->get('hwi_oauth.user_checker')->checkPostAuth($newUser); 
     } catch (AccountStatusException $e) { 
      // Don't authenticate locked, disabled or expired users 
      return; 
     } 

     $session->remove('oauth.resource'); 
     $session->remove('oauth.id'); 
     $session->getFlashBag() 
      ->add('success', 'You\'re succesfully registered!'); 

     return $this->redirectToRoute('home'); 
    } 

    return $this->render('default/register-oauth.html.twig', array(
     'form' => $form->createView() 
    )); 

} 

Der Benutzer ist nicht eingeloggt, was schade ist. Auch die normale Fosub-Funktionalität (Profil bearbeiten, Passwort ändern) funktioniert nicht mehr out-of-the-box.

Ich benutze einfach den Benutzernamen als Anzeigename, nicht sicher, warum ich das vorher nicht gesehen habe.

+0

Haben Sie die Lösung gefunden? –

+0

Meistens; Ich habe es in der Frage bearbeitet, und es scheint fast wie gewünscht zu funktionieren. Es ist eine Weile her, weiß nicht genau, wie es endete. – TacoV

Antwort

0

Schritt 1: Erstellen Sie Ihren eigenen Benutzeranbieter. Erweitern Sie den OAuthUserProvider und passen Sie ihn an Ihre Anforderungen an. Wenn der Benutzer erfolgreich angemeldet wurde, eine bestimmte Ausnahme (wahrscheinlich die accountnotlinkedException) werfen und alle relevanten Daten über die Anmeldung irgendwo werfen

Schritt 2: Erstellen Sie Ihre eigenen Authentifizierung Fehlerbehandlung. Überprüfen Sie, ob der Fehler, der ausgelöst wird, der spezifische ist, den Sie in Schritt 1 geworfen haben. Hier werden Sie auf Ihre zusätzliche Infoseite umgeleitet.

Dies ist, wie Sie benutzerdefinierte Handler registrieren:

#security.yml 
firewall: 
    main: 
     oauth: 
      success_handler: authentication_handler 
      failure_handler: social_auth_failure_handler 

#user bundle services.yml (or some other project services.yml) 
services: 
    authentication_handler: 
     class: ProjectName\UserBundle\Handler\AuthenticationHandler 
     arguments: ["@security.http_utils", {}, "@service_container"] 
     tags: 
      - { name: 'monolog.logger', channel: 'security' } 

    social_auth_failure_handler: 
     class: ProjectName\UserBundle\Handler\SocialAuthFailureHandler 
     arguments: ["@security.http_utils", {}, "@service_container"] 
     tags: 
      - { name: 'monolog.logger', channel: 'security' } 

Schritt 3: in Zusatzinfo Seite Erstellen Sie füllen. Ziehen Sie alle relevanten Daten, die Sie gespeichert haben, in Schritt 1 zurück und erstellen Sie den Benutzer, wenn alles ausgecheckt ist.

+0

Klingt gut. Ich erweitere FOSUBUserProvider, der bereits OAuthUserProvider erweitert und die AccountNotLinkedException auslöst. Ich bleibe jedoch in Schritt 2 stecken. Wie machst und registrierst du deinen eigenen Fehlerbehebungs-Handler? Ich konnte den Fehlerhandler nicht ohne einen Compiler-Durchlauf setzen (was übertrieben erschien). Ich habe versucht, den Parameter hwi_oauth.authentication.listener.oauth.class auf meine eigene Klasse (extending OAuthListener) zu setzen. Die onFailure-Methode ist jedoch wie auch die failureHandler-Variable privat. Ich werde es weiter versuchen und werde berichten, wenn ich etwas finde. – TacoV

+0

@TacoV Ich habe einige Konfigurationsbeispiele hinzugefügt. Lassen Sie Ihre Handler den DefaultAuthenticationFailureHandler bzw. DefaultAuthenticationSuccessHandler erweitern –

+0

Danke, das war der Hinweis, den ich brauchte. Die Hauptfrage (wie man den Redirect etc. injiziert) ist nun beantwortet, vielen Dank!Wenn ich ein vollständiges Arbeitsbeispiel habe, werde ich es in die Frage bearbeiten. – TacoV

Verwandte Themen