我试图改变Wordpress身份验证的行为。我有专门为我公司成员的网站,我只希望他们访问它,而无需管理大量不同的用户帐户,验证它们等。
我的想法是隐藏未登录用户的网站并向他们显示登录表单,在那里,只显示电子邮件字段(做得非常好,只是创建了带有wp-login.php副本的自定义页面并进行了重定向未登录的观众,我认为这可能是完全自定义登录页面的最佳方式。)
现在我必须改变身份验证功能的行为方式,但完全不知道如何启动它,据我所知,我必须为许多功能制作许多不同的过滤器。我完全停电了,不能
以下是注册/登录的过程:
(已完成)用户进入该页面,如果未记录,他将看到只有电子邮件字段和提交按钮的登录表单
他将输入他的电子邮件并点击提交(这里我必须摆脱"没有密码"错误信息)
如果允许电子邮件在域中(将从选项中提供允许的域数组),用户将收到一封电子邮件,其中包含要继续的链接
点击链接后,用户进入页面并通过&#34进行身份验证;记住我"设置,而无需设置任何密码等(在此之前,如果没有用户这样的电子邮件,WP将创建一个用户名包含@之前的字符和随机强密码)
因为整个身份验证系统有很多变化,所以我无法理解它。我从哪里开始修改必填字段?我应该使用哪种挂钩?
PS:我不想创建新的身份验证系统,我需要依赖修改WP功能。
已经开始工作了。 我最终创建了一个wp-login页面的副本,并将所有未登录的用户重定向到它,页面位于/ start /下。 我的主题中的page-start.php基本上是wp-login的副本,几乎没有调整(无法记住所有tbh)。
我没有提及登录表单修改和样式更改,只提及脚本。
首先,重定向已经登录用户到root(在文件的开头):
session_start();
if(is_user_logged_in()) {
wp_redirect( '/' );
exit;
}
接下来,我已经更改了部分代码来处理秘密登录字符串,如果它匹配并且还没有过期(重要),它将登录新用户。
if(isset($_GET['key'])) {
$_SESSION['let_me_in_key'] = $_GET['key'];
session_write_close();
wp_redirect(home_url('/start/'));
exit();
}
if(isset($_SESSION['let_me_in_key'])) {
global $wpdb;
$let_me_in_key = $_SESSION['let_me_in_key'];
$_SESSION['let_me_in_key'] = NULL;
unset($_SESSION['let_me_in_key']);
$sha = $let_me_in_key;
$res = $wpdb->get_results("SELECT * FROM {$wpdb->users} WHERE user_activation_key LIKE '%{$sha}'",ARRAY_A);
if (!isset($res[0])) {
$errors ->add('invalid_key', 'Nieprawidłowy klucz aktywacyjny, zaloguj się ponownie aby otrzymać nowy klucz w wiadomości email.');
} else {
$db_key = explode(':',($res[0]['user_activation_key']));
$minutes = (time()-$db_key[0]);
if($minutes > 60*60) {
$errors ->add('expired_key', 'Klucz aktywacyjny wygasł, zaloguj się ponownie aby otrzymać nowy klucz w wiadomości email.');
} else {
$user = get_userdata($res[0]['ID']);
$wpdb->query("UPDATE {$wpdb->users} SET user_activation_key = '' WHERE ID = {$user->ID}");
clean_user_cache($user->ID);
wp_clear_auth_cookie();
wp_set_current_user($user->ID);
wp_set_auth_cookie($user->ID, true, true);
update_user_caches($user);
wp_redirect(home_url());
}
}
}
这是在这部分之后添加的:
if ( $interim_login ) {
if ( ! $errors->get_error_code() )
$errors->add( 'expired', __( 'Your session has expired. Please log in to continue where you left off.' ), 'message' );
} else {
现在我已经添加了处理自定义登录的功能。
首先它会删除wp_authenticate_username_password
,然后它会添加自己的身份验证功能
它会检查电子邮件是否有效,然后是否是允许的域之一(我使用的是ACF,因此我的自定义数据由get_field()
访问)。
如果一切正确,脚本将使用wp_generate_password
生成密码(密码将不重要,因为用户不必使用它,但它更好创建比123qwe更安全的东西:D)并创建用户剥离@
并仅保留域部分中的字母数字字符(我不会在@
之前剥离部分中的任何特殊字符,但是你可以)。
remove_filter('authenticate', 'wp_authenticate_username_password', 20);
add_filter('authenticate', function($user, $email, $password){
$email = strtolower($_POST['log']);
$allowed_domains = array_map('trim',array_filter(explode(PHP_EOL, get_field('domeny','options'))));
$domain = explode("@", $email);
if($_POST['log']) {
if(!filter_var($email, FILTER_VALIDATE_EMAIL) ){ //Invalid Email
$error = new WP_Error();
$error->add('invalid_username', 'Błędny adres email.');
return $error;
}
else if(!in_array($domain[1],$allowed_domains)){ //Invalid Email
$error = new WP_Error();
$error->add('invalid_username', 'Niedozwolony adres email. Czy na pewno używasz adresu służbowego?');
return $error;
}
} else return $user;
//Check if user exists in WordPress database
$user = get_user_by('email', $email);
if(!$user){
$pass = wp_generate_password( $length=12, $include_standard_special_chars=false );
$user_id = wp_create_user( $domain[0].preg_replace("/[^a-zA-Z0-9_]+/", "",$domain[1]), $pass, $email );
wp_update_user( array( 'ID' => $user_id, 'display_name' => $email ) );
$user = get_userdata($user_id);
} else {
$user_id = $user->ID;
}
if(send_activation_link($email,$user_id)) {
$error = new WP_Error();
$error->add('confirm', 'Na podany email został wysłany link z potwierdzeniem logowania. Kliknij w link z wiadomości aby przejść dalej.', 'message');
}
return $error;
}, 20, 3);
我还必须更改wp_authenticate
才能获得用户名:
add_action( 'wp_authenticate', 'email_address_login' );
function email_address_login( &$username, &$password )
{
$user = get_user_by( 'email', $username );
if( !empty( $user->user_login ) )
{
$username = $user->user_login;
}
}
除此之外,我还必须创建一个生成密钥的函数,并发送激活链接:
function send_activation_link($email,$user_id){
add_filter( 'wp_mail_content_type', 'wpdocs_set_html_mail_content_type' );
global $wpdb, $wp_hasher;
$salt = wp_generate_password(20,false); // 20 character "random" string
$sha = sha1($salt . $email . uniqid(time(), true));
//$a_z = 'abcdefghijklmnopqrstuvwxyz';
$key_saved = $wpdb->update( $wpdb->users, array( 'user_activation_key' => time().':'.$sha ), array( 'ID' => $user_id ) );
if ( false === $key_saved ) {
return new WP_Error( 'no_password_key_update', __( 'Could not save password reset key to database.' ) );
}
/* send mail here */
remove_filter( 'wp_mail_content_type', 'wpdocs_set_html_mail_content_type' );
}
答案 0 :(得分:0)
他将输入电子邮件并点击“提交”(在这里我必须摆脱“否 密码”错误消息)
如果电子邮件位于允许的域中(允许的域数组将为 由选项提供),用户将收到一封电子邮件,其中包含要链接到 继续
这两个应该结合使用-如果存在数组中的电子邮件,请使用wp_insert_user
和自动生成的密码。
这可能是一些随机数(请参阅wp_nonce_field
)字段,该字段会在返回时进行身份验证。
这是一个漫长的问题,所以它并不是真正的“一个答案”,但是您更适合设置自己的表单并使用Ajax或类似的东西。