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

跨服务器Laravel Rest API与Angular谷歌认证配置疑问

Hey there, let’s walk through solving your Google auth issue step by step—separating Laravel API and Angular is a great architecture, but OAuth flows do need careful handling to keep things secure. Let’s tackle your specific questions first, then lay out the full workflow with code examples.

Core Approach: Use the Authorization Code Flow

First, you’ll want to use Google’s Authorization Code Flow (not the implicit flow) here—this is the secure standard for server-side apps, since it keeps your client_secret hidden from the frontend.

1. How to Handle client_secret (The Critical Part)

Let’s get this straight: never expose your client_secret to Angular or any frontend code. Frontend assets are publicly accessible, so putting your secret there is a huge security risk.

All sensitive OAuth operations (exchanging the authorization code for a token, validating tokens) must happen in your Laravel backend. Your Angular app only acts as a "middleman" to send users to the right endpoints, then receives a secure API token from Laravel once authentication is done.

2. Redirect URL Setup: Yes, Point to Laravel First

You’re on the right track here—set Google’s redirect URL to a Laravel API route, not your Angular app. Here’s why:

  • Google sends the authorization code to this URL after user login, and you need to exchange that code for a Google access token (which requires your client_secret).
  • Once Laravel verifies the user and creates a session/API token, it can then redirect back to your Angular app with that token.

Step-by-Step Google Console Configuration

  1. Open your project in the Google Developer Console.
  2. Navigate to APIs & Services > Credentials.
  3. Create a Web application OAuth client ID.
  4. Under Authorized redirect URIs, add your Laravel callback route (e.g., https://your-laravel-api.com/auth/google/callback).
  5. Save the client_id and client_secret—store these in your Laravel .env file:
    GOOGLE_CLIENT_ID=your-client-id
    GOOGLE_CLIENT_SECRET=your-client-secret
    GOOGLE_REDIRECT_URI=https://your-laravel-api.com/auth/google/callback
    

3. Full Workflow: Angular ↔ Laravel ↔ Google

Let’s map out the end-to-end flow with code examples:

Laravel Side: Set Up Auth Routes & Controller

First, define your API routes:

// routes/api.php
use App\Http\Controllers\AuthController;

Route::get('auth/google/redirect', [AuthController::class, 'redirectToGoogle']);
Route::get('auth/google/callback', [AuthController::class, 'handleGoogleCallback']);

Now create the AuthController to handle the flow:

// app/Http/Controllers/AuthController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use App\Models\User;

class AuthController extends Controller
{
    public function redirectToGoogle()
    {
        $queryParams = http_build_query([
            'client_id' => config('services.google.client_id'),
            'redirect_uri' => config('services.google.redirect'),
            'response_type' => 'code',
            'scope' => 'openid email profile',
            'access_type' => 'offline', // Optional: Get a refresh token for long-lived access
            'prompt' => 'select_account', // Force user to pick an account
        ]);

        // Redirect user to Google's auth page
        return redirect()->away('https://accounts.google.com/o/oauth2/v2/auth?' . $queryParams);
    }

    public function handleGoogleCallback(Request $request)
    {
        // Exchange authorization code for Google tokens
        $tokenResponse = Http::asForm()->post('https://oauth2.googleapis.com/token', [
            'client_id' => config('services.google.client_id'),
            'client_secret' => config('services.google.client_secret'),
            'redirect_uri' => config('services.google.redirect'),
            'code' => $request->code,
            'grant_type' => 'authorization_code',
        ]);

        $tokenData = $tokenResponse->json();

        // Validate the ID token (critical for security)
        $idToken = $tokenData['id_token'];
        $validation = Http::get('https://oauth2.googleapis.com/tokeninfo', ['id_token' => $idToken]);
        $userInfo = $validation->json();

        // Ensure the token was issued for your app
        if ($userInfo['aud'] !== config('services.google.client_id')) {
            abort(401, 'Invalid token audience');
        }

        // Create or update the user in your database
        $user = User::updateOrCreate(
            ['email' => $userInfo['email']],
            ['name' => $userInfo['name'], 'google_id' => $userInfo['sub']]
        );

        // Generate a Laravel API token (using Sanctum in this example)
        $apiToken = $user->createToken('google-auth-token')->plainTextToken;

        // Redirect back to Angular with the API token
        return redirect()->to('https://your-angular-app.com/auth/callback?token=' . $apiToken);
    }
}

Don’t forget to configure Laravel Sanctum (or Passport) if you haven’t already—this is how you generate secure API tokens for your users.

Angular Side: Trigger Login & Handle Callback

Create a login component with a Google login button:

// src/app/google-login/google-login.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-google-login',
  template: `<button class="google-btn" (click)="initiateGoogleLogin()">Login with Google</button>`
})
export class GoogleLoginComponent {
  initiateGoogleLogin(): void {
    // Send user to Laravel's redirect route
    window.location.href = 'https://your-laravel-api.com/auth/google/redirect';
  }
}

Then create a callback component to receive the API token from Laravel:

// src/app/auth-callback/auth-callback.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AuthService } from '../services/auth.service';

@Component({
  selector: 'app-auth-callback',
  template: `<div class="loading">Processing login...</div>`
})
export class AuthCallbackComponent implements OnInit {
  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private authService: AuthService
  ) {}

  ngOnInit(): void {
    this.route.queryParams.subscribe(params => {
      const apiToken = params['token'];
      if (apiToken) {
        // Store the token securely (use sessionStorage instead of localStorage if preferred)
        this.authService.setToken(apiToken);
        // Redirect to your app's home page
        this.router.navigate(['/dashboard']);
      } else {
        // Handle login failure
        this.router.navigate(['/login']);
      }
    });
  }
}

And an AuthService to manage the token:

// src/app/services/auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
export class AuthService {
  private tokenKey = 'laravel_api_token';

  constructor(private http: HttpClient) {}

  setToken(token: string): void {
    localStorage.setItem(this.tokenKey, token);
  }

  getToken(): string | null {
    return localStorage.getItem(this.tokenKey);
  }

  // Example: Use the token for API requests
  getProtectedData() {
    const headers = new HttpHeaders({
      'Authorization': `Bearer ${this.getToken()}`
    });
    return this.http.get('https://your-laravel-api.com/api/protected', { headers });
  }
}

4. Critical Notes for Security & CORS

  • CORS Configuration: Laravel needs to allow requests from your Angular domain. Update config/cors.php:
    'paths' => ['api/*', 'auth/*'],
    'allowed_origins' => ['https://your-angular-app.com'],
    'allowed_methods' => ['*'],
    'allowed_headers' => ['*'],
    'supports_credentials' => true, // Optional: If using cookies instead of query params
    
  • Token Storage: Avoid storing tokens in localStorage if your app handles sensitive data—use sessionStorage or HttpOnly cookies instead for better security.
  • Token Validation: Always validate Google’s ID token in Laravel (as shown in the controller) to ensure the user is who they claim to be.

That should cover all your confusion points! Let me know if you hit any snags with specific parts of the implementation.

内容的提问来源于stack exchange,提问作者Joy Biswas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:02:49