Your Guide to Laravel Excellence

Google Oauth Authentication from Scratch in Laravel

Google Oauth Authentication from Scratch in Laravel

Login with Google from Scratch in Laravel 10 In this step-by-step guide, we'll learn how to implement Google authentication in Laravel 10 without relying on any external authentication packages. Instead, we'll use Google's OAuth 2.0 API endpoints directly, making the integration more customizable. This method ensures better control over the Google login process and enhances user experience with a smooth, secure authentication flow.

Table of Contents

Step 2: Basic Authentication

Run the following commands to add authentication scaffolding:

composer require laravel/ui
php artisan ui bootstrap --auth
npm install

This will set up basic authentication views and routes, which you can customize.

Step 3: Configure Google OAuth 2.0 Credentials

Set up a project on Google Developers Console and add your Authorized Redirect URI, e.g., http://127.0.0.1:8000/auth/google/callback

Step 4: Configure Environment Variables

In your .env file, add:

GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://127.0.0.1:8000/auth/google/callback

These values will be used for the OAuth 2.0 flow to authenticate users via Google.

Step 5: Database Migration Setup

We need to update the users table to store additional information for Google login, such as the google_id and picture_url. Modify the create_user_table migration file as follows:

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('google_id')->nullable();
    $table->string('picture_url')->nullable();
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
    $table->rememberToken();
    $table->timestamps();
});

Now, update the User model to include the new fields in the $fillable array:

protected $fillable = [
    'name',
    'email',
    'google_id',
    'picture_url'
]

Run this command to add tables in db.

php artisan migrate 

Step 6: Create the Google Login Controller

Next, create a new controller to handle the Google login logic:

php artisan make: controller GoogleController 

In this controller, we’ll implement two main methods: one to redirect to Google's OAuth service, and another to handle the callback.

public function redirectToGoogle()
{
    $clientId = env('GOOGLE_CLIENT_ID');
    $redirectUri = env('GOOGLE_REDIRECT_URI');
    $scope = 'email%20profile'; // Requesting email and profile permissions

    // Redirect to Google's OAuth 2.0 authorization endpoint
    return redirect("https://accounts.google.com/o/oauth2/auth?client_id=$clientId&redirect_uri=$redirectUri&response_type=code&scope=$scope");
} 

Purpose: This function generates a URL that directs the user to Google's OAuth 2.0 login page.

  • clientId: The GOOGLE_CLIENT_ID from your .env file (your app's identifier in Google's OAuth system).
  • redirectUri: The URL to which Google will redirect the user after authorization, specified by GOOGLE_REDIRECT_URI in the .env file.
  • scope: This specifies what user data you're requesting permission for (email and profile in this case).
  • OAuth Flow: Redirects the user to the Google authorization page where the user can grant your app permission to access their data.
public function handleGoogleCallback(Request $request)
{
    $code = $request->query('code');
    if (empty($code)) {
        return response()->json(['error' => 'Authorization code not provided'], 400);
    }

    $clientId = env('GOOGLE_CLIENT_ID');
    $clientSecret = env('GOOGLE_CLIENT_SECRET');
    $redirectUri = env('GOOGLE_REDIRECT_URI');

    $response = Http::post('https://accounts.google.com/o/oauth2/token', [
        'code'          => $code,
        'client_id'     => $clientId,
        'client_secret' => $clientSecret,
        'redirect_uri'  => $redirectUri,
        'grant_type'    => 'authorization_code',
    ]);

    $tokens = $response->json();
    if (isset($tokens['access_token'])) {
        $accessToken = $tokens['access_token'];
        $userData = $this->getUserData($accessToken);
        $user = $this->findOrCreateUser($userData);
        $userRecord = User::where('email', $user['email'])->first();
        if ($userRecord) {
            Auth::login($userRecord, true);
            return redirect('/'); // Redirect the logged-in user
        } else {
            return redirect()->route('login');
        }
    }

    return response()->json(['error' => 'Failed to obtain access token']);
}
private function getUserData($accessToken)
{
    $response = Http::get('https://www.googleapis.com/oauth2/v3/userinfo', [
        'access_token' => $accessToken,
    ]);
    return $response->json();
}

Purpose:

  • When Google redirects back to your app, it includes a code (authorization code) in the URL.
  • The code is exchanged for an access token by making a POST request to Google's OAuth token endpoint:
  • client_id, client_secret, code, redirect_uri, and grant_type are required to request the token.
  • If successful, the response contains an access_token which will be used to access the user’s Google profile.
  • This function retrieves the authenticated user’s profile data from Google using the access token.
private function findOrCreateUser($userData)
{
    $user = User::where('email', $userData['email'])->first();

    if (!$user) {
        $user = User::create([
            'google_id' => $userData['sub'], // Google ID
            'name'      => $userData['name'],
            'email'     => $userData['email'],
            'picture_url' => $userData['picture'], // Profile picture
        ]);
    }
    return $user;
}

Step 7: Define Routes for Google Authentication

In routes/web.php, define the routes for Google login and the callback:

Auth::routes();

Route::get('/home', [App\Http\Controllers\HomeController::class, 'index']);
Route::get('auth/google', [GoogleController::class, 'redirectToGoogle']);
Route::get('auth/google/callback', [GoogleController::class, 'handleGoogleCallback']);

Step 8: Customize the Login View for Google Sign-In

Update the resources/views/auth/login.blade.php file to add a "Login with Google" button:

<a href="{{ url('auth/google') }}" class="btn btn-primary"><strong>Login with Google</strong></a>

Run and Test Your Application

php artisan serve

npm run dev

Recommeded Posts

AWS Elastic Transcoder: Convert & Stream Videos in Laravel 11

AWS Elastic Transcoder: Convert & Stream Videos in Laravel 11

AWS Elastic Transcoder: Convert & Stream Videos in Laravel 11

1 month ago Read article →
How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

1 month ago Read article →
Guide to Session Management and Flash Messages in Laravel

Guide to Session Management and Flash Messages in Laravel

Learn how to use Laravel's session management and flash messages. This comprehensive guide covers storing data, handling user states, and displaying temporary notifications in your Laravel applications.

1 month ago Read article →
Resize Images using intervention-image

Resize Images using intervention-image

Resize Images using intervention-image

1 month ago Read article →