En supposant qu'un utilisateur possède une session WordPress existante, est-il possible de prendre le cookie 'wordpress_logged_in_ [hash]', de le coder dans une chaîne de requête et de reprendre la session dans un autre navigateur?
Le cas d'utilisation que j'explore est que si un utilisateur s'est connecté à mon application mobile, j'aimerais lui donner la possibilité d'ouvrir la page WordPress qu'il visualise actuellement dans une vue Web dans un navigateur externe sans perdre sa session.
Voici (avec une certaine appréhension) une esquisse d’une solution à liaison unique qui pourrait être suffisamment sûre si l’on peut compter que l’IP est relativement constant (du moins à court terme) au téléphone, en utilisant une requête var et un transitoire basé sur $_SERVER['REMOTE_ADDR']
, bien que @Wyck et @G. M. dire, une telle porte dérobée est un risque pour la sécurité ...
// Make query var & transient name unique to site url and user's IP.
$siteurl = get_site_option( 'siteurl' );
// Could use eg $siteurl = COOKIEHASH; if handier for mobile app.
// Other stuff such as $device_id would be good if available.
define( 'WPSE173878', 'wpse173878' . md5( $siteurl . $_SERVER['REMOTE_ADDR'] ) );
add_action( 'init', function () {
if ( is_user_logged_in() ) {
if ( wpse173878_is_set_transient() ) {
$time = time();
wpse173878_set_transient( $time );
// For testing output link in footer.
add_action( 'wp_footer', function () use ( $time ) {
// Could just use time() instead as check fudged below in check_transient().
$link = add_query_arg( WPSE173878, $time, home_url( '/' ) );
echo '<a href="' . esc_attr( $link ) . '">Copy into a browser</a>';
} );
}
add_action( 'clear_auth_cookie', function() { delete_transient( WPSE173878 ); } );
} else {
if ( isset( $_GET[WPSE173878] ) ) {
wpse173878_check_transient();
}
}
} );
// Set transient.
function wpse173878_set_transient( $time ) {
$user_id = get_current_user_id();
$remember = wpse173878_remember( $user_id );
// Will be compromised if ip changes...
set_transient( WPSE173878, array( $user_id, $time, $remember ), 1 * MINUTE_IN_SECONDS );
}
// Check transient and login.
function wpse173878_check_transient() {
if ( list( $user_id, $time, $remember ) = get_transient( WPSE173878 ) ) {
// Fudge time test so that it's estimatable by mobile app.
if ( $_GET[WPSE173878] + 5 >= $time && $_GET[WPSE173878] - 5 <= $time ) {
delete_transient( WPSE173878 );
if ( $user = get_user_by( 'id', $user_id ) ) {
// Login.
wp_set_auth_cookie( $user->ID, $remember );
// Might want to do_action( 'wp_login', $user->user_login, $user );
}
}
}
// Redirect regardless.
wp_redirect( remove_query_arg( WPSE173878, wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
exit;
}
// Whether to set transient.
function wpse173878_is_set_transient() {
if ( wpse173878_is_in_webview() && ! is_admin() ) {
// Other conditions such as user pressed button are necessary.
return true;
}
return false;
}
// Are we in a webview?
function wpse173878_is_in_webview() {
// Pretend Firefox is webview for testing.
return strpos( $_SERVER['HTTP_USER_AGENT'], 'Firefox' ) !== false;
}
// From "wp-includes/user.php" wp_update_user().
function wpse173878_remember( $user_id ) {
// Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
// If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
$logged_in_cookie = wp_parse_auth_cookie( '', 'logged_in' );
/** This filter is documented in wp-includes/pluggable.php */
$default_cookie_life = apply_filters( 'auth_cookie_expiration', ( 2 * DAY_IN_SECONDS ), $user_id, false );
return ( ( $logged_in_cookie['expiration'] - time() ) > $default_cookie_life );
}