You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt+Laravel+Passport与WordPress的令牌化跨站登录共享需求

Got it, let's work through this. You've got a Nuxt + Laravel service site using Passport personal access tokens (with OTP, no password) and want to add a "Login with [Your Service Site]" button to your new WordPress product site—sharing that tokenized auth state, since miniOrange only supports Laravel's session-based auth which doesn't fit your token flow. Here's a custom solution that mimics the OAuth2 flow you're looking for:

Custom OAuth2 Flow for Sharing Laravel Passport Token Auth with WordPress

We'll build this in two main parts: configuring your Laravel backend to act as an OAuth2 provider for WordPress, then adding custom code to WordPress to handle the login button and auth flow.

1. Laravel Backend: Set Up Passport for WordPress Integration

Since you're already using Passport, we just need to configure it to support WordPress as a trusted OAuth2 client.

Step 1: Create a Passport Client for WordPress

Run this Artisan command to generate a public client for WordPress (this uses the Authorization Code Grant flow, standard for third-party login buttons):

php artisan passport:client --public

When prompted, enter your WordPress site's callback URL (e.g., https://your-wp-site.com/wp-login.php?action=nuxt-login-callback). Save the generated client_id and client_secret—you'll need these for WordPress.

Step 2: Secure a User Info Endpoint

Make sure your Laravel API has an endpoint that returns authenticated user data. Add this to your routes/api.php:

use Illuminate\Http\Request;

Route::middleware('auth:api')->get('/user', function (Request $request) {
    // Return only the user data you need for WordPress (email, name, etc.)
    return $request->user()->only(['id', 'name', 'email']);
});

This endpoint will let WordPress fetch user details once it has a valid access token.

Step 3: Optional Auto-Authorize (Skip Permission Prompt)

Since both sites are yours, you can skip the default Passport authorization prompt (the "Allow this app to access your account?" page). Add this to your AuthServiceProvider's boot method:

use Laravel\Passport\Passport;

public function boot()
{
    $this->registerPolicies();
    Passport::routes();

    // Auto-authorize your WordPress client only
    Passport::ignoreAuthorizationRequestsForClientIds([YOUR_WORDPRESS_CLIENT_ID]);
}

Replace YOUR_WORDPRESS_CLIENT_ID with the ID you saved earlier. Now users will automatically be redirected back to WordPress after logging in to your Laravel site.

Step 4: Update CORS Settings

Ensure your Laravel site allows cross-origin requests from WordPress. If you're using the fruitcake/laravel-cors package, add your WordPress domain to config/cors.php under allowed_origins:

'allowed_origins' => [
    'https://your-wp-site.com',
],

2. WordPress Side: Build the Login Button & Callback Handler

We'll add custom code to WordPress (either in your theme's functions.php or a simple custom plugin) to create the login button and handle the OAuth2 callback.

Step 1: Add the "Login with [Your Service Site]" Button

Add this code to insert the button on WordPress's default login page:

add_action('login_form', 'add_nuxt_service_login_button');
function add_nuxt_service_login_button() {
    $laravel_auth_url = 'https://your-laravel-site.com/oauth/authorize?' . http_build_query([
        'client_id' => 'YOUR_WORDPRESS_CLIENT_ID',
        'redirect_uri' => 'https://your-wp-site.com/wp-login.php?action=nuxt-login-callback',
        'response_type' => 'code',
        'scope' => '', // Leave empty unless you need specific permissions
        'state' => wp_create_nonce('nuxt_login_nonce') // CSRF protection
    ]);
    
    // Style the button to match WordPress's default login UI
    echo '<div style="margin: 16px 0;">
            <a href="' . esc_url($laravel_auth_url) . '" class="button button-primary button-large">登录通过你的服务站</a>
          </div>';
}

Replace placeholders with your actual client ID and site URLs.

Step 2: Handle the OAuth2 Callback

Add this code to process the callback from Laravel, exchange the authorization code for an access token, and log the user into WordPress:

add_action('login_init', 'handle_nuxt_service_login_callback');
function handle_nuxt_service_login_callback() {
    if (isset($_GET['action']) && $_GET['action'] === 'nuxt-login-callback') {
        // Verify CSRF token first
        if (!isset($_GET['state']) || !wp_verify_nonce($_GET['state'], 'nuxt_login_nonce')) {
            wp_die('Invalid security token. Please go back and try again.');
        }

        // Check for authorization code
        if (!isset($_GET['code'])) {
            wp_die('Authorization failed. No code received from your service site.');
        }

        // Exchange authorization code for access token
        $token_response = wp_remote_post('https://your-laravel-site.com/oauth/token', [
            'body' => [
                'grant_type' => 'authorization_code',
                'client_id' => 'YOUR_WORDPRESS_CLIENT_ID',
                'client_secret' => 'YOUR_WORDPRESS_CLIENT_SECRET',
                'redirect_uri' => 'https://your-wp-site.com/wp-login.php?action=nuxt-login-callback',
                'code' => $_GET['code']
            ]
        ]);

        if (is_wp_error($token_response)) {
            wp_die('Failed to retrieve access token: ' . $token_response->get_error_message());
        }

        $token_data = json_decode(wp_remote_retrieve_body($token_response), true);
        if (!isset($token_data['access_token'])) {
            wp_die('Invalid response from your service site. Please try again.');
        }

        // Fetch user data from Laravel API
        $user_response = wp_remote_get('https://your-laravel-site.com/api/user', [
            'headers' => [
                'Authorization' => 'Bearer ' . $token_data['access_token']
            ]
        ]);

        if (is_wp_error($user_response)) {
            wp_die('Failed to fetch your account details: ' . $user_response->get_error_message());
        }

        $user_data = json_decode(wp_remote_retrieve_body($user_response), true);
        if (!isset($user_data['email'])) {
            wp_die('Could not find your account. Please verify your login on the service site.');
        }

        // Find or create WordPress user
        $wp_user = get_user_by('email', $user_data['email']);
        if (!$wp_user) {
            // Create new user with a random password (users won't need it since they use OTP)
            $username = sanitize_user(str_replace(['@', '.'], '_', $user_data['email']));
            $user_id = wp_create_user($username, wp_generate_password(), $user_data['email']);
            $wp_user = get_user_by('id', $user_id);

            // Sync user name from Laravel (optional)
            if (isset($user_data['name'])) {
                wp_update_user([
                    'ID' => $user_id,
                    'display_name' => $user_data['name'],
                    'first_name' => explode(' ', $user_data['name'])[0] ?? '',
                    'last_name' => explode(' ', $user_data['name'])[1] ?? ''
                ]);
            }
        }

        // Log the user into WordPress
        wp_set_current_user($wp_user->ID);
        wp_set_auth_cookie($wp_user->ID);
        do_action('wp_login', $wp_user->user_login, $wp_user);

        // Redirect to WordPress admin or homepage
        wp_redirect(admin_url());
        exit;
    }
}

Again, replace all placeholders with your actual client credentials and site URLs.

3. Test the Flow

  1. Go to your WordPress login page—you'll see the new "Login with [Your Service Site]" button.
  2. Click it, and you'll be redirected to your Laravel site's OTP login page.
  3. Enter your OTP to log in.
  4. You'll be automatically redirected back to WordPress and logged in with your existing (or newly created) account.

Key Security & Maintenance Notes

  • Use HTTPS: Both sites must use HTTPS to avoid exposing sensitive tokens and OTP data.
  • Token Expiry: Passport access tokens expire by default (usually 1 hour). If you need longer sessions, you can enable refresh tokens and add logic to WordPress to refresh tokens automatically.
  • Error Handling: The code above includes basic error handling, but you can expand it to show friendlier messages or redirect users back to the login page with a notice.
  • Plugin vs Theme: For long-term maintenance, consider creating a simple custom plugin instead of adding code to your theme's functions.php—this way your code won't be lost if you switch themes.

内容的提问来源于stack exchange,提问作者Tamzid Oronno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:18:16