Using wp_set_auth_cookie without any hook

Wordpress version 4.7.5

I am following new users from Instagram, I can successfully register a new user. after registering i try to login user.

I can use a hook, but would like a better solution than the messy one I posted as it would be completely unhelpful.

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

      

also tried using the special programatic_login function from another post.

If I try var_dump

wp_get_current_user()

and $_COOKIE

below this, I get the user object for wp_get_current_user()

and array(1) { ["wordpress_test_cookie"]=> string(15) "WP Cookie check" }

for $_COOKIE

.

An important change

The code is inside a function that is attached to a hook that is called on the side of the page that is displayed after the title is displayed, so we couldn't use init here. any other way to do it, and also because of this wp_safe_redirect()

or header('Location: ')

also does not work.

An important update with what I just tried

Bypassing the dirty work

when i created a user from Instagram login, after successfully created i redirected the user to a page with a get parameter like something like ?user_id=$inserted_id

and to a wp hook, i tried to get GET['user_id']

and register it and it worked trying to find the right solution.

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
}

      

and then

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();
                }
            }
        }
    }
}

      

Rate it with a dirty trick. If id

we pass as a get parameter exists in the wp_users table, then no validation that will be logged in.

Update

I created user_meta before redirecting to profile page and after confirming user login and removed usermeta just like OTP. Try to do it better if possible.

Below code: -

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
}

      

and then

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();
                        }
                    }
                }
            }
        }
    }

      

+3


source to share


1 answer


If the headers are sent before wp_clear_auth_cookie()

or are called wp_set_auth_cookie()

, then both will work as they rely on a PHP function setcookie

. The action after_setup_theme

will take place before the headers are sent, so hook them and set the cookies to fix the problem.

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' );

      

Update:

If you render the view elements before running the function createUser

, it won't work, so we need to make sure they work completely independently of each other. Below I have put together a simple example of how to achieve this - we display a link to the view that passes the GET parameter, this parameter is picked up by the plugin and starts the action before anything is rendered, which will allow us to set a 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>

      

Update 2: If using the Instagrams Authentication API, then the explicit flow indicated by https://www.instagram.com/developer/authentication/ (most of the examples below are taken from there) is probably the best approach. Below I will briefly describe how you could have implemented it. Most of them are taken from there with added notes.

Submit user https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code

You can specify the WordPress user id as a parameter of the callback url, or if the user is not yet created and you need to save the state, then you need to create a temporary token that you can use later, associated with the specified data, or storing this client side of the data if not sensitive, which is probably easier and better as it doesn't require the user to be logged in to work.

Then the user will be logged in



Not much to say about this step - if an error occurs they will be redirected to http://your-redirect-uri?error=access_denied&error_reason=user_denied&error_description=The+user+denied+your+request

If the login is successful, the user will be redirected to http://your-redirect-uri?code=CODE

CODE

is passed back to the redirect url that we can redeem for the access token.

So, from here there are a lot of ways we can get around, but essentially what we need is a redirect endpoint that we have enough control over to send HTTP headers before the HTTP response body is sent.

Methods for approximating this (non-exhaustive list):

  • Conditional connection on pages Allowed to use Instagram templates (as in your examples). This has the advantage of not requiring additional forwarding.
  • Custom page template
  • An external script that manually loads WordPress, does what we want, and then redirects back to

So now that we have our endpoint setup, we need to buy back CODE

for the access token. Adapted this snippet from 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));

      

$ result will be the object representation of the JSON response:

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

      

From here we just create our user / authenticate with WordPress and redirect to the desired page / render the template (no need to redirect if processed through conditional interceptors) and restore the page state if needed.

+3


source







All Articles