ログインおよびログアウトするための資格情報を送信するためにajaxを使用しています。ログインフォームとログアウトフォームは、正常な応答によって返されたhtmlに置き換えられます。ログインまたはログアウトに成功すると、ページコンテンツはajaxのgetリクエストを介してロードされません。
正常にログインしてからログアウトすることはできますが、2度目にログインしようとするとcheck_admin_referer()からnonce failure(-1)を受け取ります。 2回目のログイン時に送信されたnonceが最初の送信とは異なることを確認しましたが、nonceについて理解している範囲ではそれが違います。このノンスは、ログアウト処理中にajaxリクエストに送り返されます。
セッションまたはグローバル変数のどこかに、何かを更新または保存する必要性を見過ごしていませんか。自分のコードを共有してログインおよびログアウトする最初の試みで私のコードが機能するのは、ここではあまり役に立ちません。
私が受け取るノンスがなぜ無効であるのか、誰かに何か考えがありますか?
EDITS BELOW
私のコードを見てください、それはphpとjavascriptの組み合わせです
<?php
/* the php sidebar menu for a logged in user
* this is also fetched by the ajax log in action
*/
function not_logged_in_menu() { ?>
<div class="login-form">
<h2>Login</h2>
<form method="post" action="<?php site_url(); ?>/wp-login.php" class="wp-user-form">
<div class="input-login">
<div class="loader"></div>
<input type="submit" class="login ui-btn" name="Login" value="Login" />
<span class="gzp-icon-login"></span>
</div>
<div class="input-prepend">
<span class="add-on icon-username"></span>
<input type="text" name="log" value="" class="input-medium" id="user_login" placeholder="Username" />
</div>
<?php /*<br class="clearer" />*/ ?>
<div class="input-prepend">
<span class="add-on icon-password"></span>
<input type="password" name="pwd" value="" id="user_pass" class="input-medium" placeholder="Password" />
</div>
<?php wp_nonce_field( 'ajax-login-nonce', 'security' ); ?>
</form>
</div> <?php
}
/* the php sidebar menu for a logged out user
* this is also fetched by the ajax log out action
*/
function logged_in_menu() {
global $user_identity; ?>
<div class="login-form">
<h2 class="welcome">Welcome<br /><?php echo $user_identity; ?></h2>
<a href="<?php echo wp_logout_url( home_url() ); ?>" id="logout" class="btn btn-inverse" title="Logout">Logout</a>
<div class="loader"></div>
<div class="clearer"></div>
</div> <?php
}
/* the php login ajax action */
function ajax_login(){
check_ajax_referer( 'ajax-login-nonce', 'security' ); // on the second log in attempt with no page refresh this
// function fails her
// Nonce is checked, get the POST data and sign user on
$info = array();
$info['user_login'] = $_POST['username'];
$info['user_password'] = $_POST['password'];
$info['remember'] = true;
$user = wp_signon( $info, false );
if ( is_wp_error($user) ){
echo json_encode(array('loggedin'=>false, 'message'=>__('Wrong username or password.')));
die();
}
//setting the user variables so the globals have content without an actual page load
wp_set_current_user( $user->ID, $user->user_login );
wp_set_auth_cookie( $user->ID, true, false );
do_action( 'wp_login', $user->user_login );
ob_start();
gzp_logged_in_menu();
$menu_content = ob_get_contents();
ob_end_clean();
echo json_encode(array('loggedin'=>true, 'message'=>__('Login successful, redirecting...'), 'menu_content'=>$menu_content,'user_signon'=>$user));
die();
}
add_action( 'wp_ajax_nopriv_ajaxlogin', 'ajax_login' );
/* the php log out ajax action */
function ajax_logout(){
// First check the nonce, if it fails the function will break
wp_verify_nonce( $_POST['security'], 'log-out' );
wp_logout();
ob_start();
gzp_not_logged_in_menu();
$menu_content = ob_get_contents();
ob_end_clean();
echo json_encode(array('loggedout'=>true, 'message'=>__('Logout successful, redirecting...'), 'menu_content'=>$menu_content));
die();
}
add_action( 'wp_ajax_ajaxlogout', 'ajax_logout' );
?>
<script type="text/javascript">
/* javascripted loaded in the head of page on page load */
jQuery(document).ready(function(event) {
admin_bar_login();
admin_bar_logout();
});
/* the ajax post for a log in attempt */
function admin_bar_login() {
/* login action */
jQuery('form.wp-user-form').on('submit', function(e) {
e.preventDefault();
jQuery('.login-form input.login').parent('.input-login').addClass('loading').show();
console.log(jQuery('form.wp-user-form #security').val());
jQuery.ajax({
type: 'POST',
dataType: 'json',
url: ajaxurl,
data: {
'action': 'ajaxlogin', //calls wp_ajax_nopriv_ajaxlogin
'username': jQuery('form.wp-user-form #user_login').val(),
'password': jQuery('form.wp-user-form #user_pass').val(),
'security': jQuery('form.wp-user-form #security').val()
},
success: function(data){
if (data.loggedin == true){
jQuery('.navigation-right .menu').html(data.menu_content);
AAPL_loadPage(document.location.toString(),1); //refresh the #content of the page
admin_bar_logout(); //this adds the event handler to the log out content just added
jQuery.bootstrapGrowl(data.message);
}
else if(data.loggedin == false) {
jQuery('.login-form input.login').parent('.input-login').removeClass('loading');
jQuery.bootstrapGrowl(data.message);
}
},
fail: function(data){
if(data.loggedin == 'false')
jQuery.bootstrapGrowl(data.message);
}
});
});
}
/* the ajax post for a log out attempt */
function admin_bar_logout() {
//logout action
jQuery('#logout').on('click', function(e) {
e.preventDefault();
jQuery(this).parent('.login-form').addClass('loading').show();
var href = jQuery(this).attr('href'),
vars = href.split("&"),
wp_nonce = '_wpnonce',
security = '';
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == wp_nonce){security = pair[1];}
}
jQuery.ajax({
type: 'POST',
dataType: 'json',
url: ajaxurl,
data: {
'action': 'ajaxlogout', //calls wp_ajax_ajaxlogout
'security': security,
},
success: function(data){
if (data.loggedout == true){
jQuery('.navigation-right .menu').html(data.menu_content);
AAPL_loadPage(document.location.toString(),1); //refresh the #content of the page
admin_bar_login(); //this adds the event handler to the log in content just added
jQuery.bootstrapGrowl(data.message);
}
else if(data.loggedin == false) {
jQuery('.login-form input.login').parent('.input-login').removeClass('loading');
jQuery.bootstrapGrowl(data.message);
}
},
fail: function(data){
if(data.loggedin == 'false')
jQuery.bootstrapGrowl(data.message);
}
});
});
}
</script>
以下の解決策
私の問題に対する正しい答えは以下の通りですが、私はまた私のユーザーが実際にログアウトされていないという別の問題を抱えていました。返されたナンスはログインしたナンスです。私が匿名ユーザーとしてログインしようとしたとき、nonceはwp_verify_nonce()
に対して無効でした。
私は、wp_logout()
を使ってログアウトするだけでは十分ではないことがわかりました。 $current_user
変数はまだすべてのユーザーデータを保持しており、is_user_logged_in()
はtrueを返しました。 wp_set_current_user(0)
を設定するまで、ユーザーが実際にログアウトされているのを確認できませんでした。
私はまたログインの間に一回だけのための必要性を取除いた。
そのトピックについての議論はこの記事を見てください
私はあなたのコードを実行したことはありませんでしたが、あなたのコードフローの欠点はナンスがユーザ特有であるということです。匿名ナンスは可能ですが、それは all 匿名ユーザにとっても同じであるため、その目的には役に立ちません。
そのため、どこかに不一致がある可能性があり、匿名でありながら特定のユーザーのnonceを使用しようとしています。
考慮すべきもう1つのことは、wp nonceシステムが現在のユーザーIDとsessiontoken(wordpress_logged_in _... cookie)の両方を使用することです。
Wp_verify_nonce関数のソースを見ると、ナンスと(現在と過去12時間の期間+ '|' + action + '|' + currentuser-id + '|' + sessiontoken)のハッシュとナンスが比較されます。
これらの変数のいずれかを変更すると、ハッシュが一致しなくなります。