Bagaimana cara memvalidasi pengguna dari ouside wordpress / php?

9

Saya sedang mengerjakan aplikasi ajax yang akan disematkan di halaman wordpress. Aplikasi ajax bertukar data dengan servlets berjalan pada kucing jantan. Sekarang servlets membutuhkan cara untuk menentukan apakah permintaan berasal dari pengguna yang masuk ke wordpress. Dan jika pengguna login, servlet juga harus dapat menentukan id pengguna agar dapat melakukan query database. Jika pengguna tidak mencatatnya, permintaan akan ditolak.

Jadi dengan kata lain, saya perlu membiarkan servlet melakukan permintaan hanya jika pengguna yang menyebabkan permintaan tersebut masuk ke wordpress (versi 3.3.x). Baik servlet (tomcat) dan wordpress (apache2) dijalankan pada mesin fisik yang sama dan berbagi database yang sama.

Secara teori ini dapat dengan mudah diselesaikan dengan melakukan hal berikut:

  1. Selama logon wordpress, beberapa token pengguna disimpan dalam variabel javascript.
  2. Aplikasi ajax meneruskan token pengguna ke servlet pada setiap panggilan.
  3. Servlet menggunakan token untuk query wordpress jika valid (yaitu jika pengguna login) dan melakukan atau menolak permintaan.

Pertanyaannya adalah bagaimana ini bisa diterapkan di sisi wordpress?
Karena, yang membuat teorinya sangat rumit adalah kenyataan bahwa saya belum melakukan pemrograman php.

Pertama saya berpikir untuk mengirimkan cookie wordpress_logged_in (auth) ke servlet dan membiarkan servlet meminta wordpress jika cookie auth masih valid. Tapi seperti yang terlihat, ini tidak dapat dilakukan, karena wp_validate_auth_cookie () selalu gagal, bahkan jika cookie-data pengguna yang masuk telah lewat. Solusi lain bisa dengan mengembangkan plugin yang menyimpan sessionid dan userid dalam sebuah tabel, yang dapat dengan mudah ditanyakan oleh servlets. Atau mungkin ada solusi lain ...

Davos Seaworth
sumber
Mengapa tidak menulis atau menggunakan plugin yang menawarkan otentikasi pengguna sebagai layanan AJAX? Itu bisa menggunakan seluruh tumpukan WP, dan aplikasi apa pun bisa menggunakannya dengan mengeluarkan permintaan HTTP yang sesuai. Namun, berhati-hatilah untuk melindungi kredensial pengguna Anda.
Raphael
Saya pikir saya menyatakan saya salah, saya tidak perlu layanan otentikasi ajax. Yang saya butuhkan adalah cara untuk memungkinkan servlet memvalidasi pengguna yang sudah diautentikasi. Yaitu memverifikasi jika pengguna masih masuk. Intinya adalah ini: Pengguna masuk, mengakses aplikasi ajax, yang berkomunikasi dengan servlet untuk menyimpan / mengambil data. Sekarang servlet perlu beberapa cara untuk 1) menguji jika permintaan tersebut berasal dari pengguna yang logon dan 2) mengambil id pengguna (untuk akses basis data lebih lanjut).
Davos Seaworth
Mungkin Anda harus mengedit pertanyaan Anda untuk memasukkan semua komentar itu. Lebih disukai, tunjukkan masalah Anda (!) Dan apa ide Anda. Secara khusus, berikan deskripsi langkah demi langkah yang jelas tentang proses yang Anda bayangkan.
Raphael
Saya harap pertanyaannya lebih jelas sekarang.
Davos Seaworth
bagaimana Anda akhirnya melakukannya? bisakah Anda membagikan solusi Anda? apakah Anda menggunakan XMLRPC?
pkyeck

Jawaban:

7

WordPress sudah memiliki API bawaan melalui server XMLRPC. Artinya, Anda dapat membuat permintaan XMLRPC dari aplikasi java Anda dan memverifikasi nama pengguna / kata sandi. Sayangnya, tidak ada cara untuk hanya membuktikan keasliannya.

Yang mengatakan, sangat mudah untuk roll Anda sendiri. Cukup sambungkan ke xmlrpc_methods, filter, dan tambahkan milik Anda. Kunci array yang Anda tambahkan dengan menjadi metode xmlrpc yang Anda panggil dari aplikasi Anda, dan nilainya akan menjadi fungsi yang dipanggil oleh server WordPress XMLRPC.

<?php
add_filter('xmlrpc_methods', 'wpse39662_add_login_method' );
/**
 * Filters the XMLRPC methods to allow just checking the login/pass of
 * a given users
 */
function wpse39662_add_login_method( $methods )
{
    $methods['wpse39662.login'] = 'wpse39662_check_login';
    return $methods;
}

Dan fungsi callback wpse39662_check_login,, akan mendapatkan satu argumen yang diteruskan ke sana, array hal yang dikirim ke server XMLRPC.

<?php
function wpse39662_check_login( $args )
{
    $username = $args[0];
    $password = $args[1];

    $user = wp_authenticate( $username, $password );

    if( is_wp_error( $user ) )
    {
        return false;
    }
    return true;
}

Ini semua sebagai plugin . Dengan yang terinstal dan XMLRPC diaktifkan di situs WP Anda, Anda harus dapat membuat permintaan dengan beberapa klien XMLRPC (saya yakin Java memilikinya).

Berikut kode yang saya gunakan untuk menguji di atas (klien Python XMLRPC).

>>> import xmlrpclib as xmlrpc
>>> s = xmlrpc.ServerProxy('http://wordpress.dev/xmlrpc.php')
>>> s.wpse39662.login('admin', 'password')
True
chrisguitarguy
sumber
1
Terima kasih! Ini membawa saya selangkah lebih maju! Dapatkah hal yang sama dicapai dengan menggunakan cookie autentikasi pengguna? Jadi saya tidak perlu menyimpan dan mengirim nama pengguna / pwd melalui kawat? Proyek saya terdiri dari aplikasi ajax yang disematkan ke halaman wordpress. Aplikasi ajax memanggil servlet dan servlet meminta wordpress jika pengguna diautentikasi. Saya bisa meneruskan pengguna / pwd ke aplikasi ajax dan mentransfernya ke servlet, tapi saya khawatir itu tidak akan terlalu aman. Jadi saya mencoba meneruskan konten cookie auth ke wp_validate_auth_cookie () tetapi selalu gagal.
Davos Seaworth
Saya hanya akan menghasilkan token atau sesuatu untuk pengguna dan menyimpannya di kedua ujung sistem. Lalu berikan token bolak-balik.
chrisguitarguy
2

Wordpress (saat ini) memeriksa apakah pengguna masih masuk dengan memeriksa salah satu cookie yang diberikan saat masuk. Itu membangun konten cookie ini dengan melakukan hashing. Detailnya ada di fungsi "wp_generate_auth_cookie" di /wp-includes/pluggable.php:

function wp_generate_auth_cookie($user_id, $expiration, $scheme = 'auth') {
    $user = get_userdata($user_id);

    $pass_frag = substr($user->user_pass, 8, 4);

    $key = wp_hash($user->user_login . $pass_frag . '|' . $expiration, $scheme);
    $hash = hash_hmac('md5', $user->user_login . '|' . $expiration, $key);

    $cookie = $user->user_login . '|' . $expiration . '|' . $hash;

    return apply_filters('auth_cookie', $cookie, $user_id, $expiration, $scheme);
}

Anda dapat membuat kembali algoritma ini (menggunakan ini dan fungsi auth_cookie lainnya) dalam kode Java Anda untuk melakukan pemeriksaan yang sama. JS dapat digunakan untuk memastikan cookie dikirimkan ke servlet Anda.

Kalau tidak, XMLRPC mungkin ide yang bagus. Anda dapat menulis metode baru (seperti yang dijelaskan dalam solusi lain di sini) untuk memvalidasi cookie auth (alih-alih memvalidasi nama pengguna dan kata sandi seperti biasanya dilakukan).

laughingbovine
sumber
2

Dapatkan plugin Exec-PHP , lalu buat halaman WordPress (bukan pos) dengan permalink yang bagus ( http://mysite/user_id/) dan kode pada get_current_user_id()referensi API :

<?php
$user_id = get_current_user_id();
if ($user_id == 0) {
    echo 'You are currently not logged in.';
} else {
    echo 'You are logged in as user '.$user_id.'.';
}
?>

Anda kemudian dapat mengekstrak cookie yang dikirim klien kepada Anda dan memasukkannya ke dalam GETpermintaan http://127.0.0.1/user_id/. Kemudian Anda akan tahu apakah pengguna itu login dan apa ID pengguna mereka.

Olathe
sumber
1

Anda dapat melakukan sesuatu seperti ini di halaman non-wp:

<?php
require('./wp-blog-header.php');
// Make sure ^ points to the root of your WP installation

if ( is_user_logged_in() ) {
   // Perform your request here
}

?>
FlashingCursor
sumber
Terima kasih atas jawabannya, masalahnya adalah, servlets ditulis dalam java, jadi kode php tidak dapat dijalankan. Apa yang saya cari adalah semacam antarmuka eksternal yang memungkinkan servlet / java untuk berkomunikasi dengan wordpress / php. Tentu saja ada beberapa jenis antarmuka yang tersedia, saya hanya tidak dapat menemukannya ...
Davos Seaworth
Ah, begitu. Mungkin menggunakan sesuatu seperti Quercus caucho.com/resin-3.0/quercus mungkin memberi Anda yang terbaik dari kedua dunia?
FlashingCursor
Terima kasih, tetapi quercus adalah solusi yang salah, karena saya sudah memiliki instalasi wordpress / php / apache yang berfungsi dan instalasi servlet / java / tomcat yang berfungsi. Sekarang satu-satunya yang saya butuhkan adalah antarmuka antara keduanya, yang memungkinkan servlet memverifikasi jika pengguna masuk ke wordpress (beberapa antarmuka / protocoll / ipc / apa pun).
Davos Seaworth
1

Ini adalah plugin WordPress satu-file yang berfungsi:

function yournamespace_validateAuthCookie($cookie, $scheme = 'logged_in') {
    return wp_validate_auth_cookie($cookie, $scheme);
}

function yournamespace_new_xmlrpc_methods($methods) {
    $methods['yournamespace.validateAuthCookie'] = 'yournamespace_validateAuthCookie';
    return $methods;
}
add_filter('xmlrpc_methods', 'yournamespace_new_xmlrpc_methods');

Pada dasarnya memperlihatkan metode XML-RPC baru yang dengannya Anda dapat meminta WordPress untuk memvalidasi wordpress_logged_in_...cookie.

Anda kemudian perlu menulis beberapa kode untuk menanyakan metode ini dan memberikannya nilai wordpress_logged_in_...cookie.

Metode ini akan mengembalikan false(jika cookie tidak divalidasi) atau ID pengguna jika validasi berhasil.

kYuZz
sumber