используя wp, установите аутентификационный файл cookie без какого-либо крючка


Версия Wordpress 4.7.5

Я регистрирую новых пользователей из Instagram, я успешно зарегистрировал нового пользователя. после регистрации я пытаюсь войти в систему пользователя.

Я могу использовать крюк, но хотел бы получить лучшее решение, чем грязное, я опубликовал, так как это будет совершенно бесполезно.

if( $user_created ) {
    $new_user = get_user_by( 'id', $user_created ); 
    //$loggedin = programmatic_login( $new_user->user_login );
    //ob_start();
    if ( !is_user_logged_in() ) {
        wp_clear_auth_cookie();
        wp_set_current_user( $user_created, $new_user->user_login );
        wp_set_auth_cookie( $user_created, true );
        do_action( 'wp_login', $new_user->user_login );
        // wp_safe_redirect(site_url() . '/profile/');
        // exit;
        // $redirect_to=user_admin_url();
        // wp_safe_redirect($redirect_to);
        // exit();
    }
    //ob_end_clean();
} ?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo site_url() . '/profile/'; ?>";});</script> <?php

Также пробовал использовать пользовательскую функцию programmatic_login из другого поста.

Если я пытаюсь var_dump wp_get_current_user() и $_COOKIE ниже это, я получаю объект пользователя для wp_get_current_user() и array(1) { ["wordpress_test_cookie"]=> string(15) "WP Cookie check" } для $_COOKIE .

Важное изменение

Код находится внутри функции, которая подключена к крючку, который вызывается на стороне страницы, которая отображается после заголовка, поэтому мы не могли использовать здесь инициализацию. любой другой способ сделать это, а также из-за этого wp_safe_redirect() или header('Location: ') также не работает.

Важное обновление с тем, что я только что попробовал

Грязная работа вокруг

Когда Я создал пользователя из входа в Instagram, после успешного создания я перенаправил пользователя на страницу с параметром get что-то вроде ?user_id=$inserted_id и на крючке wp я попытался получить GET['user_id'] и зарегистрировал его, и это сработало, пытаясь найти правильное решение.

if ( $wpdb->insert_id ){  //that is registration with instagram
   ?>
    <script>jQuery(document).ready(function(){ window.location.href = "<?php echo get_bloginfo('url') . '/profile/?id=' . $wpdb->insert_id; ?>";});</script>
   <?php
}

И затем

add_action( 'wp', 'login_current_user' );
function login_current_user(){
    if ( is_page() && get_the_id() == 863 ){
        if ( isset( $_GET['id'] ) ){
            if ( !is_user_logged_in() ) {
                $user_id = $_GET['id'];
                $user = get_user_by( 'id', $user_id ); 
                wp_clear_auth_cookie();
                wp_set_current_user( $user_id, $user->user_login );
                wp_set_auth_cookie( $user_id, true );
                do_action( 'wp_login', $user->user_login );
                if ( is_user_logged_in() ){
                    $redirect_to=site_url() . '/profile';
                    wp_safe_redirect($redirect_to);
                    exit();
                }
            }
        }
    }
}

Проблема с грязным трюком. Если id мы передаем в качестве параметра get существует в таблице wp_users, то без проверки, которая будет зарегистрирована .

Обновление

Я создал пользовательскую метку перед перенаправлением на страницу профиля и после проверки входа в систему пользователя и удалил пользовательскую метку, как и OTP. Пытаясь сделать это лучше, если это возможно.

Ниже кода: -

if ( $wpdb->insert_id ){  //that is registration with instagram
    $temporary_token = sha1(rand());
    update_user_meta( $wpdb->insert_id, 'temporary_token', $temporary_token);
   ?>
    <script>jQuery(document).ready(function(){ window.location.href = "<?php echo get_bloginfo('url') . '/profile/?id=' . $wpdb->insert_id . '&token=' . $temporary_token; ?>";});</script>
   <?php
}

И затем

add_action( 'wp', 'login_current_user' );
    function login_current_user(){
        if ( is_page() && get_the_id() == 863 ){
            if ( isset( $_GET['id'] ) ){
                if ( !is_user_logged_in() ) {
                    $user_id = $_GET['id'];
                    $user = get_user_by( 'id', $user_id );
                    if ( $_GET['token'] == get_user_meta( $user_id, 'temporary_token', true ) ){
                        delete_user_meta( $user_id, 'temporary_token', $_GET['token'] ); 
                        wp_clear_auth_cookie();
                        wp_set_current_user( $user_id, $user->user_login );
                        wp_set_auth_cookie( $user_id, true );
                        do_action( 'wp_login', $user->user_login );
                        if ( is_user_logged_in() ){
                            $redirect_to=site_url() . '/profile';
                            wp_safe_redirect($redirect_to);
                            exit();
                        }
                    }
                }
            }
        }
    }
Author: Prafulla Kumar Sahu, 2017-06-02

1 answers

Если заголовки были отправлены до вызова wp_clear_auth_cookie() или wp_set_auth_cookie(), то ни один из них не будет работать, так как оба полагаются на функцию PHP setcookie. Действие after_setup_theme произойдет до того, как заголовки будут отправлены таким образом, чтобы зацепить их и установить файлы cookie, чтобы устранить проблему.

function myPlugin_createUser(){
  // Probably need to put code that creates user here too otherwise $user_created will never return true
  if( $user_created ) {
      $new_user = get_user_by( 'id', $user_created ); 
      if ( !is_user_logged_in() ) {
          wp_clear_auth_cookie();
          wp_set_current_user( $user_created, $new_user->user_login );
          wp_set_auth_cookie( $user_created, true );
          do_action( 'wp_login', $new_user->user_login );
      }
  } 
}

add_action( 'after_setup_theme', 'myPlugin_createUser' );

Обновление:

Если вы выводите элементы представления перед запуском функции createUser, она не будет работать, поэтому нам нужно убедиться, что они работают полностью независимо друг от друга. Ниже я собрал простой пример того, как этого добиться - в представлении мы выводим ссылку, которая передает параметр GET, этот параметр подхватывается плагином и запускает действие до того, как что-либо будет отображено, позволяя нам установить файл cookie.

My-plugin.php

// Note: you'll need to include a completed version of myPlugin_createUser() function as above for these examples to work
add_shortcode( 'my-plugin', function() {  
   // I've used a GET request for simplicity- a form + POST request may be more practical for your purposes and will prevent caching issues.
   echo "<a href='?my_plugin_login_user=1'>Login</a>";
});

// Check for our GET parameter 
if( isset( $_GET['my_plugin_login_user'] ) ) {
  // Nothing should be rendered yet as plugin template hasn't even started loading yet so cookies should set fine
  add_action( 'plugins_loaded', 'myPlugin_createUser' ); 
}

Page-my-template.php

<div> ...
    <?php 
        do_shortcode( 'my-plugin' ); 
    ?>
</div>

Обновление 2: При использовании API аутентификации Instagram описан явный поток https://www.instagram.com/developer/authentication / (большая часть примеры, используемые ниже, взяты оттуда), вероятно, лучший подход. Ниже я дам краткое описание того, как вы могли бы это реализовать. Большая часть этого взята оттуда с добавлением заметок.

Отправьте пользователя на https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code

Вы можете включить идентификатор пользователя WordPress в качестве параметра в URL обратного вызова или, если пользователь еще не создан, и вам необходимо поддерживать состояние, то вам нужно будет сгенерировать временный токен, который вы сможете использовать позже, связанный с указанными данными, или сохранить эти данные на стороне клиента, если они не являются конфиденциальными, что, вероятно, проще и лучше, так как для этого не требуется, чтобы пользователь вошел в систему для работы.

Затем пользователь войдет в систему

Не так много можно сказать об этом шаге - в случае возникновения ошибки они будут перенаправлены на http://your-redirect-uri?error=access_denied&error_reason=user_denied&error_description=The+user+denied+your+request

Если вход в систему пройдет успешно, пользователь будет перенаправлен на http://your-redirect-uri?code=CODE

CODE, переданный обратно по URL-адресу перенаправления, мы можем обменять на токен доступа.

Итак, отсюда есть множество способов, которыми мы можем справиться с этим, но, по сути, нам нужна конечная точка для перенаправления, над которой у нас есть достаточный контроль для отправки HTTP-заголовков до отправки любого тела HTTP-ответа.

Методы приближения к этому (не исчерпывающий список):

  • Допускается условное подключение к страницам Instagram (как в ваши примеры). Это имеет то преимущество, что не требует дополнительного перенаправления.
  • Пользовательский шаблон страницы
  • Внешний скрипт, который вручную загружает WordPress, делает то, что нам нужно, а затем перенаправляет обратно в

Итак, теперь, когда у нас есть настройка конечной точки, нам нужно обменять CODE на токен доступа. Адаптированный этот фрагмент из https://gist.github.com/arturmamedov/7f5a90b85a20e06e344ebb88dc898d25

$uri = 'https://api.instagram.com/oauth/access_token'; 
$data = [
    'client_id' => '213esdaedasdasd12...YOUR_CLIENT_ID', 
    'client_secret' => 'a8b4aaf06c0da310...YOUR_CLIENT_SECRET', 
    'grant_type' => 'authorization_code', 
    'redirect_uri' => 'http://www.YOUR_REDIRECT_URL.it',      // The exact redirect URL as used previously
    'code' => $_GET['code']  
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri); // uri
curl_setopt($ch, CURLOPT_POST, true); // POST
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // POST DATA
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // RETURN RESULT true
curl_setopt($ch, CURLOPT_HEADER, 0); // RETURN HEADER false
curl_setopt($ch, CURLOPT_NOBODY, 0); // NO RETURN BODY false / we need the body to return
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // VERIFY SSL HOST false
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // VERIFY SSL PEER false
$result = json_decode(curl_exec($ch));

$результатом будет объект представление ответа JSON:

{
"access_token": "fb2e77d.47a0479900504cb3ab4a1f626d174d2d",
"user": {
    "id": "1574083",
    "username": "snoopdogg",
    "full_name": "Snoop Dogg",
    "profile_picture": "..."
  }
}

Отсюда мы просто создаем нашего пользователя/аутентифицируемся с помощью WordPress и перенаправляем на нужную страницу/визуализируем шаблон (нет необходимости перенаправлять, если обрабатывается с помощью условных крючков) и восстанавливаем состояние страницы, если это необходимо.

 3
Author: Brian, 2017-06-06 07:45:02