Last active
December 4, 2025 15:11
-
-
Save campusboy87/9fa31f35dce933d48a5204d978e92c29 to your computer and use it in GitHub Desktop.
WordPress WP-CLI плагин для генерации временных ссылок входа (auto-login links) с автоматическим удалением после использования или через 5 минут.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Plugin Name: Temp Login Links (WP-CLI) | |
| * Description: Генерация временных ссылок для входа через WP-CLI. | |
| * Version: 1.3 | |
| * Author: campusboy | |
| * | |
| * Скачать к себе в текущую директрою | |
| * curl -L https://gist.github.com/campusboy87/9fa31f35dce933d48a5204d978e92c29/raw -o wp-login-cli.php | |
| * | |
| * Dev notes / examples: | |
| * wp temp-login create [email protected] | |
| * wp temp-login create 123 --minutes=10 | |
| * wp temp-login create username --minutes=5 | |
| * | |
| * wp user list --role=administrator --fields=ID,user_login,user_email | |
| * wp user meta list 123 | |
| * URL: https://example.com/?temp_login_token=<token> | |
| */ | |
| if ( ! defined( 'ABSPATH' ) ) { | |
| exit; | |
| } | |
| class WP_CLI_Login { | |
| private string $token; | |
| private $user_id; | |
| public function __construct() { | |
| $this->token = $_GET['temp_login_token'] ?? ''; | |
| if ( $this->token ) { | |
| $this->token = wp_unslash( $_GET['temp_login_token'] ); | |
| $this->user_id = $this->get_once_user_id_by_token(); | |
| if ( $this->user_id ) { | |
| add_action( 'init', [ $this, 'auth' ] ); | |
| // Отключаем WP 2FA при входе через temp_login_token | |
| define( 'DISABLE_2FA_LOGIN', true ); | |
| } else { | |
| wp_die( 'Invalid or expired token', 'Temp Login', [ 'response' => 403 ] ); | |
| } | |
| } | |
| } | |
| /** | |
| * Авторизовываем | |
| * | |
| * @return void | |
| */ | |
| public function auth() { | |
| $user = get_user_by( 'id', $this->user_id ); | |
| if ( ! $user ) { | |
| wp_die( 'User not found', 'Temp Login', [ 'response' => 404 ] ); | |
| } | |
| wp_clear_auth_cookie(); | |
| wp_set_current_user( $user->ID ); | |
| wp_set_auth_cookie( $user->ID, true ); | |
| do_action( 'wp_login', $user->user_login, $user ); | |
| wp_redirect( home_url() ); | |
| exit; | |
| } | |
| /** | |
| * Получает ID пользователя по токену разовой авторизации | |
| * | |
| * @return false|int | |
| */ | |
| private function get_once_user_id_by_token() { | |
| static $user_id = null; | |
| if ( $user_id !== null ) { | |
| return $user_id; | |
| } | |
| global $wpdb; | |
| // Ищем пользователя с этим токеном | |
| $result = $wpdb->get_row( $wpdb->prepare( | |
| "SELECT user_id, meta_value FROM {$wpdb->usermeta} | |
| WHERE meta_key = %s", | |
| 'temp_login_token_' . $this->token | |
| ) ); | |
| if ( ! $result ) { | |
| return false; | |
| } | |
| $data = maybe_unserialize( $result->meta_value ); | |
| $user_id = (int) $result->user_id; | |
| // Проверяем срок действия | |
| if ( ! isset( $data['expires'] ) || $data['expires'] < time() ) { | |
| delete_user_meta( $user_id, 'temp_login_token_' . $this->token ); | |
| return false; | |
| } | |
| // Удаляем токен после использования (одноразовый) | |
| delete_user_meta( $user_id, 'temp_login_token_' . $this->token ); | |
| return $user_id; | |
| } | |
| } | |
| new WP_CLI_Login(); | |
| if ( defined( 'WP_CLI' ) && WP_CLI ) { | |
| class Temp_Login_CLI_Command { | |
| public function create( $args, $assoc_args ) { | |
| if ( empty( $args[0] ) ) { | |
| WP_CLI::error( 'Specify user ID, login or email.' ); | |
| } | |
| $who = $args[0]; | |
| $user = null; | |
| if ( is_numeric( $who ) ) { | |
| $user = get_user_by( 'id', intval( $who ) ); | |
| } | |
| if ( ! $user ) { | |
| $user = get_user_by( 'login', $who ); | |
| } | |
| if ( ! $user ) { | |
| $user = get_user_by( 'email', $who ); | |
| } | |
| if ( ! $user ) { | |
| WP_CLI::error( 'User not found.' ); | |
| } | |
| $minutes = isset( $assoc_args['minutes'] ) ? intval( $assoc_args['minutes'] ) : 5; | |
| if ( $minutes <= 0 ) { | |
| $minutes = 5; | |
| } | |
| $token = wp_generate_password( 64, false, false ); | |
| $expires = time() + ( $minutes * MINUTE_IN_SECONDS ); | |
| // Сохраняем токен в user meta | |
| update_user_meta( $user->ID, 'temp_login_token_' . $token, [ | |
| 'expires' => $expires, | |
| 'created' => time(), | |
| ] ); | |
| $url = add_query_arg( 'temp_login_token', $token, site_url( '/' ) ); | |
| WP_CLI::success( $url ); | |
| } | |
| /** | |
| * Очистка истекших токенов | |
| */ | |
| public function cleanup( $args, $assoc_args ) { | |
| global $wpdb; | |
| $meta_keys = $wpdb->get_results( | |
| "SELECT umeta_id, user_id, meta_key, meta_value | |
| FROM {$wpdb->usermeta} | |
| WHERE meta_key LIKE 'temp_login_token_%'" | |
| ); | |
| $cleaned = 0; | |
| foreach ( $meta_keys as $meta ) { | |
| $data = maybe_unserialize( $meta->meta_value ); | |
| if ( isset( $data['expires'] ) && $data['expires'] < time() ) { | |
| delete_metadata_by_mid( 'user', $meta->umeta_id ); | |
| $cleaned ++; | |
| } | |
| } | |
| WP_CLI::success( "Cleaned {$cleaned} expired tokens." ); | |
| } | |
| } | |
| WP_CLI::add_command( 'temp-login', 'Temp_Login_CLI_Command' ); | |
| } |
Author
Полезная штука, особенно где кучу юзеров...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Запрашиваем, к примеру, ссылку для автологина для пользователя с ID=1818
Получаем: