可以通过查询字符串将WordPress会话转移到不同的浏览器吗?

时间:2015-01-03 作者:Jacob Tabak

假设用户已有WordPress会话,是否可以获取“WordPress\\u logged\\u in\\uHash]”cookie,将其编码为查询字符串,然后在其他浏览器中恢复会话?

我正在探索的具体用例是,如果用户已登录到我的移动应用程序,我想让他们可以选择在外部浏览器的webview中打开当前正在查看的WordPress页面,而不会丢失会话。

1 个回复
SO网友:bonger

这里(有点担心)是一个一次性使用链接解决方案的草图,如果可以依赖于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 );
}

结束