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.