Chào các bạn, hôm nay Wolfactive tụi mình sẽ chia sẽ cho các bạn về cách đăng kí user trên WP khi người dùng đăng kí tài khoản khi người dùng đăng ký tài khoản. Bên cạnh đó tụi mình cũng sẽ hướng dẫn các bạn làm sao cho bảo mật và hiểu quả nhất. Giờ chúng ta bắt đầu tìm hiểu nhé.
Hướng dẫn đăng kí người dùng với REST API
1/ Tạo form đăng kí
Đầu tiên để các bạn có thể đăng ký user thì các bạn cần phải tạo form đăng kí trước!
<div class="form-create-account">
<div class="form-field">
<label for="first-name">First Name</label>
<input type="text" name="firstName" id="first-name" class="form-field-item">
</div>
<div class="form-field">
<label for="last-name">Last Name</label>
<input type="text" name="lastName" id="last-name" class="form-field-item">
</div>
<div class="form-field">
<label for="email">Your Email Address *</label>
<input type="text" name="email" id="email" class="form-field-item">
</div>
<div class="form-field">
<label for="password">Your Password *</label>
<input type="password" name="password" id="password" class="form-field-item">
</div>
<div class="form-field">
<a href="javascript:void(0)" class="btn btn-submit-create-account">Create Account</a>
</div>
</div>
Sau khi tạo form xong thì các bạn cần phải tạo REST API để đưa dữ liệu người dùng lên và lưu lại trong db website các bạn có thể đọc kỹ hơn ở bài Custom Api Endpoint Post Request. Nên ở bài này mình sẽ ko đi chi tiết về api nữa.
2/ Tạo Custom Api Endpoint Post Request
2.1/ Tạo API và callback function thực thi
Trước hết tụi mình sẽ tạo đường dẫn api bằng register_rest_route:
add_action('rest_api_init','submitCreateAccount');
function WAsubmitCreateAccount(){
register_rest_route('user-api/v1','/save-data',array(
'methods' => "POST",
'callback' => 'WAsubmitDataToDb',
'permission_callback' => '__return_true',
));
}
function WAsubmitDataToDb($request){
$submit = WAprefix_userSubmitDB();
return rest_ensure_response($submit);
}
Như các bạn thấy ở đây mình tạo hai function. WAsubmitCreateAccount để tạo đường dẫn api và callback hàm WAsubmitDataToDb để thực thi. Bên trong WAsubmitDataToDb thì mình sẽ gọi tiếp một hàm để xử lí chương trình.
2.2/ Tạo function thực thi
Ở trên mục 2.1, ở function thứ 2 mình có gọi hàm WAprefix_userSubmitDB() vào $submit. Nên bây giờ tụi mình sẽ bắt đầu tạo hàm này nhé:
function WAprefix_userSubmitDB(){
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if ($contentType === "application/json") {
//Receive the RAW post data.
$content = trim(file_get_contents("php://input"));
$decoded = json_decode($content, true);
// setup default result data
$result = array(
'status' => 0,
'message' => array(),
'error'=>'',
);
if (wp_verify_nonce( $decoded['wp_rest'], 'wp_rest' )) {
$firstName = $decoded['firstName'];
$lastName = $decoded['lastName'];
$username = $firstName.$lastName;
$email = $decoded['email'];
$password = $decoded['password'];
$checkUserName = username_exists( $username );
$checkEmail = email_exists( $email );
if(!$checkEmail===false && $checkUserName){
$result['error']='error';
array_push($result['message'],"Username already exists, please you need change it");
array_push($result['message'],"Email already exists, please you need change it");
}
else if($checkUserName){
$result['error']='error';
array_push($result['message'],"Username already exists, please you need change it");
} else if(!$checkEmail===false){
$result['error']='error';
array_push($result['message'],"Email already exists, please you need change it");
}
else if(!$checkUserName && $checkEmail===false){
$user_data = [
'user_login' => $username,
'user_pass' => $password,
'user_email' => $email,
'first_name' => $firstName,
'last_name' => $lastName,
'role' => 'shopmember',
];
$user_id = wp_insert_user( $user_data );
if ( $user_id ) {
wa_ajax_auto_login($username,$password);
}
}
}
user_return_json($result);
// process form data
}
}
Như các bạn thấy ở function này mình có làm khác đi so với việc xử lí dữ liệu khi đưa lên api ở bài Custom Api Endpoint Post Request. Đó là mình có sử dụng hàm wp_verify_nonce( $decoded[‘wp_rest’], ‘wp_rest’ ). Hàm này sử dụng nhằm mục đích là để kiểm tra nonce của người dùng có đúng với nonce truyền lên api hay ko. Nếu đúng thì mới thực thi đoạn code bên trong. Việc này mình làm như vậy là để bảo mật khi các bạn gửi request lên api, bên cạnh đó các bạn cũng nên đăng kí SSL để tăng độ bảo mật website nếu chưa có nhé.
Giờ mình sẽ giải thích wp_verify_nonce() cho các bạn hiểu. Ở đây mình sử dụng một hàm là wp_create_nonce() để tạo 1 key nonce, mỗi người dùng sẽ có 1 key riêng và khi refesh lại thì sẽ thay đổi. Các bạn có thể đặt nó trong một element nào đó để các bạn có thể thuận tiện lấy ra khi check. Còn check như thế nào thì mình sẽ nói ở mục kế tiếp. Ví dụ mình tạo một nonce với tên là wp_create_nonce(‘wp_rest’). Thì khi mình check sẽ lấy key đó ra như trên mình sử dụng wp_verify_nonce( $decoded[‘wp_rest’], ‘wp_rest’ )
Kế tiếp mình sử dụng hàm wp_insert_user để add user vào db. Sở dĩ có 2 hàm để add account, một là hàm mình đang sử dung, 2 là hàm wp_create_user . Tuy nhiên mình sử dụng wp_insert_user vì nó có thể truyền vào nhiều tham số. Còn wp_create_user bạn chỉ có thể truyền vào UserName, Password, Email. Sau khi add thành công thì hàm sẽ trả về cho mình là 1 id user. Ta sẽ check xem $user_id đó có tồn tại hay ko? Nếu có thì sẽ tự động login khi mình gọi hàm wa_ajax_auto_login (cách tạo mình sẽ ghi chi tiết sau).
Cuối cùng thì mình trả về ở dạng json để giao tiếp api
function user_return_json( $php_array ) {
// encode result as json string
$json_result = json_encode( $php_array );
// return result
die( $json_result );
// stop all other processing
exit;
}
3/ Tạo Function automatically login
function wa_ajax_auto_login($user_login,$user_pass) {
$creds = array(
'user_login' => $user_login,
'user_password' => $user_pass,
'remember' => true
);
$user = wp_signon( $creds, false );
}
4/ Xử lí API
let btnSubmitDataUser = document.querySelector('.btn.btn-submit-create-account'); let messageErrorContain = document.querySelector('.notice-des-create-account'); let messageError = document.querySelector('.info-des-list'); if(btnSubmitDataUser){ btnSubmitDataUser.onclick = () =>{ let fistName = document.querySelector('#first-name').value; let lastName = document.querySelector('#last-name').value; let email = document.querySelector('#email').value; let userName = fistName+lastName; let password = document.querySelector('#password').value; let apiUrlUser =<code>${apiObject.homeurl}/wp-json/user-api/v1/save-data?_wpnonce=${apiObject.nonce}
; fetch(apiUrlUser,{ method: 'POST', mode: 'cors', headers: { 'Content-Type': 'application/json', // sent request 'Accept': 'application/json' // expected data sent back }, body: JSON.stringify({ 'firstName': fistName, 'lastName':lastName, 'email':email, 'userName':userName, 'password':password, 'wp_rest':apiObject.nonce, }) }) .then(response => response.json()) .then(data => { if(data.error === "error"){ messageError.innerHTML = ""; if(messageErrorContain.classList.contains('d--none')){ messageErrorContain.classList.remove('d--none'); if(data.message.length>0){ for(let i = 0; i <data.message.length;i++){ messageError.innerHTML +=<div class="info-des-item">${data.message[i]}</div>
; } } } else { if(data.message.length>0){ for(let i = 0; i <data.message.length;i++){ messageError.innerHTML +=<div class="info-des-item">${data.message[i]}</div>
; } } } } else { if(!messageErrorContain.classList.contains('d--none')){ messageErrorContain.classList.remove('d--none'); } location.replace(apiObject.homeurl); } return data; }) } }
headers: {
'Content-Type': 'application/json', // sent request
'Accept': 'application/json' // expected data sent back
'X-WP-Nonce': apiObject.nonce,
},

Để fix lỗi trên thì các bạn cần làm như sau mình sẽ chia thành các TH cho các bạn dễ hình dung nhé.
TH1: nếu các bạn đặt nonce trong headers.
<code>${apiObject.homeurl}/wp-json/user-api/v1/save-data?_wpnonce=${apiObject.nonce}
;
<code>${apiObject.homeurl}/wp-json/user-api/v1/save-data?wp_rest=${apiObject.nonce}
;