0

I am creating a membership site where I am trying to login a particular user from a link sent to their email address.

I have a custom post typed called "Members", where I have stored a unique key with the name "user_key". After a particular process, the email is sent to that user with an auto login link.

An example link looks like the following

http://example.com/process/?key=DcP2K7cmBUrLVRjizs78RAuuoMGRFc6F6TMDm6E6

Process is the page which handles the login part. Here is the code used in that page.

get_header();

$key = $_GET['key'];
$args = array(
    'post_type' => 'member',
    'meta_value' => $key
);

$properties = new WP_Query($args);

if($properties->have_posts()) : 
    while($properties->have_posts()) : $properties->the_post();
        $author = $post->post_author;

        $user = get_user_by('ID', $author);
        $user_id = $user->ID;

        echo $user_id;

        wp_set_current_user($user_id, $loginusername);
        wp_set_auth_cookie($user_id);
        do_action('wp_login', $loginusername);

        wp_redirect( home_url() );
    endwhile;
endif;
wp_reset_query();

get_footer();

When I go to that particular link, I get the following error.

"Warning: Cannot modify header information - headers already sent"

From what I understand, I think it's the "wp_set_auth_cookie" part which is done after the headers are loaded, which is creating that problem.

Anyone has any ideas how to fix it?

3
  • why do you need a header and footer? if the user is logged in the page gets redirected. if you wish to display an error message in case of failure, put the header and footer in that code block.
    – inarilo
    Commented Dec 13, 2017 at 19:19
  • Thanks for the tip! I was also thinking it might be something to do with the header part loading before. The reason why I did that was to show them a "loading" animation during the process. Anyways I guess have to skip that part now. Thanks again. Cheers.
    – Patrick S
    Commented Dec 13, 2017 at 21:24
  • i'm adding it as an answer, as for loading, you can do that, first load the page and then use ajax to log them in
    – inarilo
    Commented Dec 13, 2017 at 21:30

2 Answers 2

0

You can't send headers after there is already some output. If you wish to add content to display if the redirect fails, put the header and footer in the relevant code block:

//login code
//if redirect happens, code execution halts, so there is no need for an if else

get_header();
//error message
get_footer();
0

A better approach will be having the user_id in the URL (maybe not even a plain text $code = get_user_meta( $user_id, 'activation_account_token', true ); and checking the token from user are the same - out of scope for this question).

The reason for the error is this line echo $user_id;

wp_clear_auth_cookie();
wp_set_current_user ( $user->ID );
wp_set_auth_cookie  ( $user->ID );
wp_redirect( home_url() );

You shouldn't output anything before the redirect takes place.

Updated

You have a few option on how you can handle the redirect:

Inside the theme template moving the redirect code above the get_header();

function.php /plugin

A better option will be using the wp_loaded that is triggered before any HTML will be output.

add_action ('wp_loaded', 'login_redirect');
    function login_redirect() {
        if ( isset( $_GET['key'] ) ) {
            $user = get_users(array(
                'meta_key'     => 'key_or_the_name_you_use',
                'meta_value'     => $_GET['key'] ,
                'number' => 1,
            ));
            if(count($user) == 1){
                $user_id =$user[0]->ID;
                wp_clear_auth_cookie();
                wp_set_current_user ( $user_id  );
                wp_set_auth_cookie  ( $user_id );
                wp_redirect( home_url() );
                exit;
            }

        }
    }

This is What you can actually do but I think you misread my answer as including the user id can increase the security not decrease it.

Including the user_id can bind the user id with the token so someone brute forcing URLs to make them login will also have to match the random string with the user id account (this is what actually the industry does) - with more, of course, security checks.

Javascript

echo "<script>location.href='get_home_url()'</script>";

This can be output in the position of the wp_redirect to make the browser make the redirect.

But as this is a browser redirect user may have blocked the execution of Javascript or the redirects.

2
  • Hello, Thanks for answering. The main reason why I have a unique generated key is to avoid people accessing other accounts directly, for example the user ID can be changed from 17 to 18, then that person will be logged in to someone else's account. As far as the code is concerned. the echo was just for testing. I have removed that but I still get that error.
    – Patrick S
    Commented Dec 13, 2017 at 20:55
  • @PatrickS I think you misread my answer as this is a more secure way of handling tokens. I have updated my answer and hope this makes it more clear how you can handle the redirect and authentication process. Commented Dec 14, 2017 at 6:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.