web-dev-qa-db-ja.com

ページをリロードせずにWordPress Ajaxログイン

私は現在、ユーザーがサイトに登録またはログインする前に画像をアップロードできるようにしたいというWordPressテーマを開発しています。

最初の問題は、あなたが登録ユーザーでなければwp.media JavaScriptクラスを使ってWordPressに画像をアップロードすることができないということでした。

私が作成したソリューションは、実際には非常に単純です。

  1. ユーザーが登録ページに到着すると、JavaScriptコードがユーザーがログインしているかどうかを確認します。そうでない場合は、ランダムな電子メールとパスワードを使用して一時ユーザーを作成し、この新しく作成された一時ユーザーで訪問者にログインしますバックグラウンドで。その後、ユーザーが自分のデータに登録すると、この一時的なユーザーは正しい訪問者データで更新されます。

  2. 今トリッキーな部分。 WordPressがこのユーザーをページのリロードなしでログインしていると識別して動作させるために、アクションset_logged_in_cookieに関数を追加したので、WordPressがこの新しいログインユーザーに設定しようとしている$_COOKIEデータを取得できます。 ajax呼び出しを通して、私はこのクッキーデータをローカルユーザーのコンピューターにJavaScriptで設定します。

これでクッキーの正しいデータを取得でき(PHPは問題なく動作しました)、問題なく設定できました(JavaScriptも問題なく動作しているようです)。ページのリロード後に$_COOKIEグローバルをダンプした場合、JavaScriptコードのajax呼び出しで取得したのと同じデータが表示されますが、CookieをJavaScriptコードで設定した後、リロードせずにwp.mediaを使用してアップロードしようとします。ページがリロードされた後は、うまく機能します。

どんな訴訟?ベローは私の現在のコードです(私は関連するコードだけを残しました):

 // 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;
       }

それでは、フロントエンドのJavaScriptコードで、データを取得してCookieを設定します(または少なくとも試してみます)。

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

JavaScriptでJavaScriptを使用してクライアント側で設定できるようにwordpress_logged_in_HASH cookie情報をjavascriptで利用できるようにしようとしている場合(したがって、ページの再レンダリングを回避する必要がある場合)、 。 wordpress_logged_inクッキーはhttponlyクッキーです。つまり、クライアント上でそれにアクセスすることはできません。また、これをXSSに対して脆弱にするのでjavascriptに公開するべきではありません。詳細についてはここを参照してください。 http://blog.codinghorror.com/protecting-your-cookies-httponly/

1
James Cat

あなたの問題はおそらくあなたのコールバックから始まります。

public function handleAjax( $action )

JSONエラーまたは成功を送信するためには、ただコールする必要があります。

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

応答は以下のようになります。

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

両方の関数は内部的に wp_send_json() を呼び出します。これは適切なheaderを設定します。

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

そしてあなたのためにJSONにエンコーディングをします:

echo json_encode( $response );

設定されたCookieフィルタに対するあなたのコールバックは決して呼び出されないので機能しません。一段階上に進んで wp_set_auth_cookie() を使ってください。あなたのユーザ登録はすでにそれを許可しているはずです:後の登録フックの1つがすでに存在するユーザIDを持っている:user_registerまたはwpmu_new_userは両方ともその場合うまくいくはずです。

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