web-dev-qa-db-ja.com

adminとしてログインしたときにwp_verify_nonceが常にfalseを返す

私は自分のプラグインにAJAX機能をいくつか実装しました、そしてそれが私がadminとしてログインしていない限りうまく働きます - それからwp_verify_nonceは失敗します。それは無許可ユーザーおよび許可された一般ユーザーにも機能します。

これが私のPHPクラスです(私は問題に関係のないものをすべて削除しました):

class My_Ajax {
    function __construct() {
        add_action( 'wp_ajax_geoip_citylist', array($this, 'geoip_citylist') );
        add_action( 'wp_ajax_nopriv_geoip_citylist', array($this, 'geoip_citylist') );
        add_action( 'wp_enqueue_scripts', array($this, 'geoip_localize_js'), 11 );
    }

    function geoip_citylist() {
        if ( ! wp_verify_nonce($_POST['geoipNonce'], 'my_geoip_nonce') ) {
            exit('Wrong nonce: ' . $_POST['geoipNonce']);
        }
    }


    function geoip_localize_js() {
        wp_localize_script(
            'my_custom_js', 'myGeoipAjaxObject', 
            array( 
                'myGeoipNonce' => wp_create_nonce('my_geoip_nonce')
            ) 
        );
    }
}

これが私のJavascriptです。

$.ajax({
    url: myMainAjaxObject.ajaxUrl,
    type: 'POST',
    dataType: 'json',
    data: {
        geoipNonce: myGeoipAjaxObject.myGeoipNonce,
        action: "geoip_citylist"
    },
    success: function(data) {
        replacePhones(data.user_city, data.current_phone, data.city_list);
    },
    error: function(error) {
        console.log(error);
    }
});

PHPエラー応答のノンスは正しいようですが、それでもまだ何らかの理由で検証されていません。

何が問題なのかを突き止め、これを可能な限りあらゆる方法でグーグルしようとするのに何日も費やしたが、今のところうまくいく解決策を見つけることができなかった。 2011年に作成された this one のように、スタックオーバーフローに関して同様の問題を抱えた未解決の質問があります。 Wordpressの管理者アカウントが、私は少なくともあきらめる前に確認を得たいと思います。

UPDATE:ここで提供したコードだけを使用しようとしましたが、それでも同じエラーが発生しました(キャッシュもダブルチェックしたところ、更新されました)。

UPDATE 2:myMainAjaxObjectとそのajaxUrlは別のスクリプトに挿入されます。 AJAX URLはすべてのAJAXリクエストで同じなので、毎回それを再定義するのではなく、グローバルなものを使用します。したがって、これがエラーの原因ではありません。また、定義されていなければ、機能しません。繰り返しになりますが、管理者だけでは機能しません。他のユーザーや権限のないユーザーにとっては問題ありません。管理者としてログインしたときに、サーバーの応答に「間違ったnonce:73dd02f662」と表示されます。だから私は100%URLが正しいことを確信しています。

1
Dmitriy Gamolin

問題は、テスト中にクッキーを手動で数回削除したことだと思います。その中には、 "wordpress_logged_in_ {token}"というクッキーがありました。{token}は一意の識別子です。私の一番の推測は、このクッキーの欠如が一回だけの作成や検証に問題を引き起こしたということです。私はまだ管理パネルを閲覧することができたので(それはWPが "wordpress_ {token}"と呼ばれる別のクッキーを使用しているように見えます)どこにでもユーザーのステータスを表示します(アカウントは使用されていませんが、ログイン機能は表示されていません)。

解決策は非常に簡単でした - 私は管理者として再ログインしただけで私のAJAXも管理者のために働き始めました。したがって、誰かが同様の問題に遭遇した場合、あなたがクッキーをクリアするとき、あなたが削除/再生成する必要があるものだけを削除するか、あなたが私のようにそれらすべてを削除するなら、必ずadminとして再ログインすること.

シモンズ:最初からすべての詳細を提供しなかったのは残念ですが、必要なだけ多くの情報を提供しようとしました。私は何かが足りないことを知っていました、そして今、私はこの質問をすることさえ愚かだと感じます。しかし、私はそれを削除するつもりはないので、同じ問題にぶつかった人が時間を節約することができるかもしれません。

6
Dmitriy Gamolin

WordPressのAjax URLはhttps://examle.com/wp-admin/admin-ajax.phpのようなものです。あなたがログインしておらず、あなたがフロントエンドにいるときは、URLをスクリプトに渡す必要があります。

あなたのコードでは、これを使用しています:

url: myMainAjaxObject.ajaxUrl,

しかしmyMainAjaxObject.ajaxUrlは定義されていません。あなたはこれのようにそれをすることができました:

wp_localize_script(
    'my_custom_js', 'myGeoipAjaxObject', 
    array( 
        'myGeoipNonce' => wp_create_nonce('my_geoip_nonce'),
        'ajaxUrl'      => admin_url( 'admin-ajax.php' )
    )
);

これで、フロントエンドやログインしていないユーザーにmyMainAjaxObject.ajaxUrlを使用できます。

2
cybmeta