这里(有点担心)是一个一次性使用链接解决方案的草图,如果可以依赖于ip对电话相当稳定(至少在短期内),那么该解决方案可能足够安全,使用查询var和基于$_SERVER[\'REMOTE_ADDR\']
, 虽然正如@Wyck和@G.M.所说,任何这样的后门都有安全风险。。。
// 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 );
}