Hier (mit ein wenig Angst) ist eine Skizze einer einmal verwendeten Link-Lösung, die sicher genug sein könnte, wenn man sich darauf verlassen kann, dass die IP-Adresse (zumindest kurzfristig) mit einer Abfrage var und a ziemlich konstant zum Telefon ist vorübergehend, basierend auf $_SERVER['REMOTE_ADDR']
, wie @Wyck und @GM sagen, ist eine solche Hintertür ein Sicherheitsrisiko ...
// 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 );
}