如何让Laravel和WordPress共享登录?

问题描述 投票:2回答:2

我是Laravel开发人员。我用Laravel开发了一个电子商务插件,我只想将WordPress与Laravel结合起来。所以我需要在Laravel和WordPress之间共享或进行常见的登录会话。

我怎么能实现这个?是否有专门的插件可用于此?或者我可以使用laravel-Auth?

wordpress laravel authentication oauth laravel-5.2
2个回答
0
投票

正确的方法是将Laravel(或Wordpress)作为Auth服务器并创建类似SSO插件。从Laravel登陆NodeBB论坛我也是如此。

我建议的步骤:

  1. 看看这个包Laravel OAuth Server
  2. 为wordpress创建或查找任何SSO插件

所以你有laravel(注册等)的所有用户,如果他们想登录到Wordpress,他们登录Laravel App并授予登录wordpress的权限。想想看就像你添加Facebook Login to your site更多地了解wordpress SSO

但是要使用会话和cookie,可能会出现安全问题。希望帮助。


0
投票

在WordPress中启用单点登录花了我18个多小时的努力,但可能只需要几分钟:

我尝试了各种各样的东西:Laravel Passport(OAuth2),OpenID Connect等。

但是,我能够解决的唯一解决方案是将WordPress登录页面重定向到生成JWT(JSON Web令牌)的经过身份验证的Laravel路由,并重定向回WordPress上的特殊回调URL,该URL可以创建新用户或登录现有用户。

它运作良好。

class JwtController extends Controller {

    /**
     * Inspired by https://github.com/WebDevStudios/aad-first-party-sso-wordpress/tree/master/lib/php-jwt
     * 
     * @param Request $request
     * @return ResponseInterface
     */
    public function redirectWithToken(Request $request) {
        $key = config('jwt.key');
        $wpJwtUrl = $request->input('callback');
        $redirectUrlAfterLogin = $request->input('redirect_to'); //Get the original intended destination and append as URL param to /jwt. 
        $tokenArray = $this->getToken(auth()->user(), $redirectUrlAfterLogin);
        $jwt = \Firebase\JWT\JWT::encode($tokenArray, $key);
        $wpJwtUrlWithTokenAsParam = $wpJwtUrl . '?token=' . $jwt;
        return redirect()->away($wpJwtUrlWithTokenAsParam);
    }

    /**
     * 
     * @param \App\User $user
     * @param string $redirectUrlAfterLogin
     * @return array
     */
    public function getToken($user, $redirectUrlAfterLogin) {
        $now = \Carbon\Carbon::now();
        $aud = config('jwt.audience'); //root URL of the WordPress site
        $firstName = StrT::getFirstNameFromFullName($user->name);
        $expirationMins = config('jwt.expirationMins');
        $token = [
            "iss" => url("/"),
            "aud" => $aud, //"audience" https://tools.ietf.org/html/rfc7519#section-4.1.3
            "iat" => $now->timestamp, //"issued at" https://tools.ietf.org/html/rfc7519#section-4.1.6
            "exp" => $now->addMinutes($expirationMins)->timestamp, //"expiration" https://tools.ietf.org/html/rfc7519#section-4.1.4
            "attributes" => [
                'emailAddress' => $user->email,
                'firstName' => $firstName,
                'lastName' => StrT::getLastNameFromFullName($user->name),
                'nickname' => $firstName,
                'displayName' => $user->name,
                'redirectUrlAfterLogin' => $redirectUrlAfterLogin//In plugin: use redirectUrlAfterLogin from attributes after login.
            ]
        ];
        return $token;
    }
}

然后编辑它的auth.php为:

// register the callback
add_action('rest_api_init', function () {
    register_rest_route('jwt-auth/v1', 'callback', [
        'methods' => 'GET',
        'callback' => 'ja_login'
            ], true);
});

require_once('JWT.php');

function ja_login() {
    //get all attributes
    $options = get_option('ja_settings');
    $token_name = $options['token_name'];
    $secret_key = $options['secret_key'];
    $iss = $options['iss'];
    $aud = $options['aud'];

    // decode the token
    $token = $_GET[$token_name];
    $key = $secret_key;
    $JWT = new JWT;
    $json = $JWT->decode($token, $key);
    $jwt = json_decode($json, true);

    // use unix time for comparision
    $exp = is_int($jwt['exp']) ? $jwt['exp'] : strtotime($jwt['exp']);
    $nbf = $jwt['nbf'] ?? null;
    $now = strtotime("now");

    // if authentication successful
    if (($jwt['iss'] == $iss) && ($jwt['aud'] == $aud) && ($exp > $now) && ($now > $nbf)) {
        return getUserFromValidToken($options, $jwt);
    } else {
        return 'Login failed. Please let us know exactly what happened, and we will help you out right away.';
    }
}

/**
 * 
 * @param array $options
 * @param array $jwt
 * @return string
 */
function getUserFromValidToken($options, $jwt) {
    $attributesKey = $options['attributes'];
    $mail = $options['mail'];
    $givenname = $options['first_name'];
    $surname = $options['last_name'];
    $nickname = $options['nickname'];
    $displayname = $options['displayname'];
    $default_role = $options['default_role'];    
    $attributes = $jwt[$attributesKey];
    $redirectUrlAfterLogin = $attributes['redirectUrlAfterLogin'] ?? get_site_url();
    $_SESSION['attributes'] = $attributes;
    $_SESSION['jwt'] = $jwt;

    // find or create user
    $user = ja_find_or_create_user($attributes[$mail], $attributes[$mail], $attributes[$givenname], $attributes[$surname], $attributes[$nickname], $attributes[$displayname], $default_role);
    // login user
    if ($user) {
        wp_clear_auth_cookie();
        wp_set_current_user($user->ID, $user->user_login);
        wp_set_auth_cookie($user->ID);
        do_action('wp_login', $user->user_login);        
        wp_safe_redirect($redirectUrlAfterLogin);
        exit();
    } else {
        return 'getUserFromValidToken failed!';
    }
}

/**
 * 
 * @param string $username
 * @param string $emailAddress
 * @param string $firstName
 * @param string $lastName
 * @param string $nickname
 * @param string $displayName
 * @param string $defaultRole
 * @return mixed 
 */
function ja_find_or_create_user($username, $emailAddress, $firstName, $lastName, $nickname, $displayName, $defaultRole) {
    // if user exists, return user
    if (username_exists($username)) {
        return get_user_by('login', $username);
    } elseif (email_exists($emailAddress)) {
        return get_user_by('email', $emailAddress);
    } else {//  create user
        $length = 16;
        $include_standard_special_chars = false;
        $random_password = wp_generate_password($length, $include_standard_special_chars);
        // create user
        $user_id = wp_create_user($username, $random_password, $emailAddress);
        // update user metadata and return user id
        $userData = [
            'ID' => $user_id,
            'first_name' => $firstName,
            'last_name' => $lastName,
            'nickname' => $nickname,
            'display_name' => $displayName,
            'role' => $defaultRole
        ];
        return wp_update_user($userData);//(If successful, returns the user_id, otherwise returns a WP_Error object.)
    }
}

/**
 * Get login message link HTML for adding to the login form
 * @return string
 */
function getLoginMessage() {
    $options = get_option('ja_settings');
    $redirect_to = $_GET['redirect_to'] ?? null;
    $login_url = $options['login_url'] . '?callback=' . urlencode(site_url('/wp-json/jwt-auth/v1/callback'));
    if($redirect_to){
        $login_url .= '&redirect_to=' . urlencode($redirect_to);
    }
    $login_message = $options['login_message'];
    return "<a id='jwt_link' href='{$login_url}'>{$login_message}</a>";
}

add_filter('login_message', 'getLoginMessage');
add_action( 'load-profile.php', function() {//https://wordpress.stackexchange.com/a/195370/51462 Redirect from profile.php to the dashboard since there is no reason for WordPress users to see or manage their profile since their main account is on the other site.
    if( ! current_user_can( 'manage_options' ) ){
        $redirectUrl = get_site_url();//admin_url()
        exit( wp_safe_redirect( $redirectUrl ) );
    }
} );
function show_admin_bar_conditionally(){//remove the WordPress admin toolbar https://premium.wpmudev.org/blog/remove-the-wordpress-admin-toolbar/
    return current_user_can( 'manage_options' );
}
add_filter('show_admin_bar', 'show_admin_bar_conditionally');//can use 'show_admin_bar_conditionally' or '__return_false' for never.
//------------------------------------------------------------------
//for https://wordpress.org/support/topic/rest-api-26/#post-9915078 
//and https://github.com/kevinvess/wp-force-login/issues/35 
//and https://wordpress.org/support/topic/rest-api-26/page/2/#post-10000740
//and https://wordpress.org/support/topic/jwt-authentication/#post-10698307
add_filter( 'rest_authentication_errors', '__return_true' );

这属于WordPress中主题的functions.php:

// https://codex.wordpress.org/Customizing_the_Login_Form
function my_custom_login_page() { ?>
    <style type="text/css">
        #loginform, #login #nav{display: none;}
        #jwt_link{font-weight: bold; font-size: 20px;}
    </style>
    <script>
        document.addEventListener("DOMContentLoaded", function(event) { 
            document.getElementById('jwt_link').click();//immediately upon load of login page, click the JWT link automatically
        });
    </script>
<?php }
add_action( 'login_enqueue_scripts', 'my_custom_login_page' );
© www.soinside.com 2019 - 2024. All rights reserved.