web-dev-qa-db-fra.com

WordPress Ajax Connexion sans rechargement de page

Je développe actuellement un thème WordPress dans lequel je souhaite que l'utilisateur puisse télécharger des images avant de s'inscrire ou de se connecter au site.

Le problème initial était, vous ne pouvez pas télécharger des images vers WordPress à l'aide de la classe JavaScript wp.media si vous n'êtes pas un utilisateur enregistré.

La solution que je crée est en réalité très simple:

  1. Lorsque l'utilisateur arrive sur la page d'inscription, un code JavaScript vérifie si l'utilisateur est connecté ou non. Sinon, nous créons un utilisateur temporaire avec un e-mail et un mot de passe aléatoires et connectons le visiteur avec cet utilisateur temporaire nouvellement créé. en arrière-plan. Après cela, l'idée est qu'une fois que l'utilisateur s'enregistre avec ses propres données, cet utilisateur temporaire sera mis à jour avec les données de visiteur correctes.

  2. Maintenant la partie la plus délicate. Je souhaite que WordPress identifie cet utilisateur comme étant connecté sans rechargement de page, pour que cela fonctionne, j'ai ajouté une fonction à l'action set_logged_in_cookie afin de pouvoir obtenir les données $_COOKIE que WordPress va définir pour ce nouvel utilisateur connecté et les récupérer. via l'appel ajax, j'ai ensuite défini ces données de cookie dans l'ordinateur de l'utilisateur local avec JavaScript.

Maintenant, je peux obtenir les données correctes pour le cookie (PHP fonctionne parfaitement) et le configurer sans problème (JavaScript semble également fonctionner correctement). Si je vide le $_COOKIE global après un rechargement de page, je reçois les mêmes données que je reçois dans l'appel ajax de code JavaScript, mais après avoir défini le cookie, dans le code JavaScript, sans rechargement et lorsque j'essaie de télécharger avec le wp.media rien ne fonctionne, après un rechargement de page cela fonctionne très bien.

Des sugestions? Le code ci-dessous est mon code actuel (je n'ai laissé que le code correspondant):

 // set action to get the cookie data
 $this->setAction('set_logged_in_cookie', 'setCookieContents');
 public function setCookieContents($logged_in_cookie, $expire, $expiration, $user_id)
 {
     $this->_cookieContents = array(
         'logged_in_cookie'  =>  $logged_in_cookie,
         'expire'            =>  $expire,
         'expiration'        =>  $expiration,
         'user_id'           =>  $user_id
     );
 }

...

 public function handleAjax( $action )
 {

   header('Content-type: application/json');

   $action     =   PlulzTools::getValue('todo');

   $response = array(
       'status'    =>  'ok',
       'data'      =>  array()
   );

   switch($action)
   {
          case 'ajaxlogin' :
                 $response['data']['cookie'] = array(
                       'key'   =>  LOGGED_IN_COOKIE,
                       'data'  =>  $this->_cookieContents['logged_in_cookie']
                 );

                 echo json_encode($response);
          break;
       }

Maintenant, dans le code JavaScript frontal, récupérez les données et définissez le cookie (ou du moins, essayez de le faire):

jQuery.ajax({
     url : Frontend.ajaxurl,
     type: 'POST',
     data: EnviarLogin,
     timeout: 12000
}).done(function(newresponse){

     if(newresponse.status == 'ok')
     {
          // atualizando status de login
          logged = true;

          jQuery.cookie(newresponse.data.cookie.key, newresponse.data.cookie.data);

     }
}).error(function (xhr, ajaxOptions, thrownError){

     console.log(xhr);
     console.log('Erro! Status:' + xhr.status + '; Erro thrown: ' + thrownError, + ' Description: ' + xhr.statusText);

     return false;

});
3
Fabio

Si vous essayez de rendre les informations de cookie wordpress_logged_in_HASH disponibles au javascript afin de les définir côté client à l'aide de javascript (et d'éviter ainsi le re-rendu de la page), alors je pense que vous aurez plus de succès à ré-architecturer pour trouver une autre solution . Le cookie wordpress_logged_in est un cookie httponly, ce qui signifie que vous n'y avez pas accès sur le client et que vous ne devez pas l'exposer à javascript, car cela le rend vulnérable à XSS. Voir ici pour plus de détails: http://blog.codinghorror.com/protecting-your-cookies-httponly/

1
James Cat

Votre problème commence probablement par votre rappel:

public function handleAjax( $action )

Pour envoyer une erreur JSON ou un succès, il vous suffit d'appeler

wp_send_json_success( array( /* Data */ ) );
wp_send_json_error( array( /* Data */ ) );

La réponse sera comme:

{
    success : true,
    data : [
        // Some data as key/value pairs
    ]
}

Les deux fonctions appellent en interne wp_send_json() . Ceci définit la header appropriée:

@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );

et fait l’encodage JSON pour vous:

echo json_encode( $response );

Votre rappel sur le filtre de cookie défini ne fonctionnera pas car il ne sera jamais appelé. Mieux vaut aller d'un niveau et utiliser wp_set_auth_cookie() . Votre enregistrement d’utilisateur devrait déjà permettre que l’un des hooks d’enregistrement les plus récents ait déjà l’ID utilisateur présent: user_register ou wpmu_new_user devrait tous les deux fonctionner pour ce cas.

add_action( 'user_register', wpse136539userRegistration' );
function wpse136539userRegistration( $id )
{
    $user = get_user_by( 'id', $id );

    # @TODO Custom Error handling needed here
    if ( is_wp_error( $user ) )
        return;

    wp_set_current_user( $id );
    // Log the user in - set Cookie and let the browser remember it
    wp_set_auth_cookie( $id, TRUE );

    // Redirect user to his admin profile page ... @TODO maybe somewhere else
    exit( wp_safe_redirect( user_admin_url() ) );
}
1
kaiser