0

Series Thực hành SSO | Bài 1: Khởi tạo "Trái tim" hệ thống - Dựng SSO Server (Identity Provider)

Chào anh em, trải qua 5 bài lý thuyết ròng rã, anh em đã hiểu bản chất của các giao thức, Token và luồng chạy của Single Sign-On (SSO). Nhưng lý thuyết mãi là lý thuyết nếu chúng ta không tự tay gõ ra một dòng code nào.

Bắt đầu từ bài viết này, chúng ta sẽ cùng nhau xây dựng một hệ thống SSO hoàn chỉnh từ con số 0. Kịch bản thực hành của chúng ta sẽ gồm 2 hệ thống độc lập:

  1. SSO Server (Identity Provider - IdP): Nơi quản lý thông tin User, chịu trách nhiệm cấp phát Token và xác thực. (Chạy ở domain: sso-server.test)
  2. Client App (Service Provider - SP): Ứng dụng nghiệp vụ, ví dụ như trang quản lý bán hàng hay hệ thống bán vé. Ứng dụng này KHÔNG lưu mật khẩu của user, mà sẽ "nhờ" SSO Server xác thực hộ. (Chạy ở domain: client-app.test)

Hôm nay, ở Bài 1, chúng ta sẽ đặt những viên gạch đầu tiên: Xây dựng SSO Server bằng cách sử dụng sức mạnh của Laravel Passport.

1. Khởi tạo Project và Cài đặt Laravel Passport

Mở terminal lên và tạo một project Laravel mới tinh. Ở đây mình dùng phiên bản Laravel mới nhất.

composer create-project laravel/laravel sso-server
cd sso-server

Tiếp theo, để biến ứng dụng Laravel bình thường này thành một OAuth2 Server đúng chuẩn (hỗ trợ đầy đủ Authorization Code Flow mà chúng ta học ở bài lý thuyết số 4), hãy cài đặt package laravel/passport.

composer require laravel/passport

Cấu hình file .env kết nối tới database của bạn (ví dụ dùng MySQL):

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sso_db
DB_USERNAME=root
DB_PASSWORD=

Chạy lệnh Migration để tạo các bảng mặc định của Laravel (users) và các bảng phục vụ cho OAuth2 của Passport (oauth_clients, oauth_access_tokens...):

php artisan migrate

2. Cài đặt "Chìa khóa" mã hóa

Khác với JWT thông thường, Passport sử dụng cặp khóa mã hóa bất đối xứng (Public/Private keys) để sinh ra và xác thực Access Token một cách cực kỳ bảo mật.

Chạy lệnh sau để sinh ra cặp khóa này, đồng thời tạo ra các "Client" mặc định (Personal Access Client và Password Grant Client) trong database:

php artisan passport:install

Lưu ý: Bạn sẽ thấy terminal in ra 2 chuỗi Client ID và Client Secret. Hãy tạm bỏ qua chúng, ở bài sau khi tạo Client App, chúng ta sẽ tự tay tạo một Client riêng.

3. Cấu hình hệ thống lõi

Bây giờ, chúng ta cần khai báo cho Laravel biết rằng nó sẽ sử dụng Passport làm cơ quan kiểm duyệt danh tính.

Bước 1: Sửa Model User

Mở file app/Models/User.php, thêm trait HasApiTokens của Passport vào (lưu ý import đúng namespace, không dùng Sanctum nhé).

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens; // Quan trọng: Dùng của Passport

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
    
    // ...
}

Bước 2: Cấu hình Auth Guard

Mở file config/auth.php. Kéo xuống phần guards, cấu hình guard api chuyển sang dùng passport thay vì token hay sanctum mặc định.

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport', // Đổi dòng này thành passport
        'provider' => 'users',
    ],
],

4. Tùy biến giao diện Phê duyệt (Authorization View)

Nếu anh em nhớ lại luồng Authorization Code Flow, sẽ có một bước mà hệ thống hỏi người dùng: "Ứng dụng Client App đang muốn truy cập vào thông tin của bạn. Bạn có đồng ý không?".

Mặc định, Laravel Passport đã tích hợp sẵn cái View này, nhưng nó nằm ẩn bên trong package. Để việt hóa hoặc làm đẹp nó theo chuẩn UI của công ty, anh em cần publish nó ra ngoài:

php artisan vendor:publish --tag=passport-views

Lúc này, một file resources/views/vendor/passport/authorize.blade.php sẽ xuất hiện. Anh em hoàn toàn có thể mở file này ra, chèn thêm Bootstrap hay TailwindCSS để tùy biến giao diện cấp quyền tùy thích.

Tổng kết Bài 1

Chỉ với vài lệnh đơn giản, chúng ta đã hô biến một project Laravel trống rỗng thành một OAuth2 Identity Provider thực thụ, được trang bị tận răng các bảng database quản lý Client, Token và cặp khóa mã hóa.

Đừng quên tạo sẵn 1 vài user mẫu trong database để bài sau chúng ta có tài khoản đăng nhập nhé (có thể dùng Tinker hoặc Seeder):

\App\Models\User::factory()->create([
    'name' => 'Test User',
    'email' => 'test@example.com',
    'password' => bcrypt('password123')
]);

Trái tim của hệ thống đã bắt đầu đập. Ở Bài 2, chúng ta sẽ dựng ứng dụng Client App, đăng ký nó với SSO Server này và thực hiện cú "Bắt tay" (Handshake) đầu tiên theo chuẩn Authorization Code Flow!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí