承接 unimontes-cead/sso-client 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

unimontes-cead/sso-client

Composer 安装命令:

composer require unimontes-cead/sso-client

包简介

Socialite driver and client-app integration helpers for the UNIMONTES CEAD SSO.

README 文档

README

Laravel Socialite driver + login glue for applications that authenticate through the UNIMONTES CEAD SSO (a Laravel Passport authorization server).

What this package does

  • Registers a sso Socialite driver against the SSO's own OAuth2 endpoints (/oauth/authorize, /oauth/token, /api/user) — no manual config/services.php entry needed.
  • Exposes the data returned by the SSO as a typed SsoUser DTO (id, name, email, cpf, phone, avatarUrl, roles) instead of a generic array. Every field but id is nullable: the SSO omits a field entirely when this client wasn't granted the matching scope, so null means "not authorized to see this", not "empty".
  • roles is an array of SsoUserRole (name, value, startDate, endDate) — every role the user currently holds on the SSO (a user can hold more than one at once, each with its own date range). value is the SSO's internal role ID, stable across relabeling, so it's the safer thing to persist if you want to correlate SSO roles against your own local roles — or just use it directly as your local role. SsoUser::hasRole(int $value): bool is a shortcut for checking membership.
  • Defines Contracts\SsoAuthenticatable, an interface your own User model implements to say how SSO data maps to a local user.
  • Optionally registers ready-made GET {prefix}/redirect, GET {prefix}/callback, and POST {prefix}/logout routes that do the full login/logout round-trip for you.

Scopes are the SSO's decision, not this app's

The driver always requests every scope the SSO knows about (name,email,cpf,phone,avatar,role) — there's no SSO_SCOPES env var to configure here. That's intentional: the SSO's ScopeRepository clips whatever's requested down to whatever an admin actually granted this client on the SSO's own "Aplicações" screen, regardless of what's asked for. So requesting everything unconditionally is safe — you only ever get back what the SSO already decided this client is allowed to see — and it means scope configuration lives in exactly one place (the SSO), not duplicated into every client's .env.

Installation

composer require unimontes-cead/sso-client
composer require laravel/socialite

Laravel's package auto-discovery registers SsoClientServiceProvider automatically — no manual entry in bootstrap/providers.php needed.

Configuration

Publish the config file:

php artisan vendor:publish --tag=sso-config

Set these in .env (get SSO_CLIENT_ID/SSO_CLIENT_SECRET from an admin on the SSO's "Aplicações" screen — its "URL inicial" doesn't need to point here, but its registered redirect URIs must include your callback URL):

SSO_BASE_URL=https://sso.unimontes.example
SSO_CLIENT_ID=
SSO_CLIENT_SECRET=
# Only needed if you disable the built-in routes below and drive
# Socialite yourself with a different callback path.
# SSO_REDIRECT_URI=https://your-app.example/auth/sso/callback
SSO_ROUTES_ENABLED=true
SSO_USER_MODEL=App\Models\User

Implementing the contract

Your App\Models\User must implement SsoAuthenticatable::fromSsoData() — it receives the SsoUser DTO and returns the local user to log in as, typically an updateOrCreate() keyed on the SSO's id:

use UnimontesCead\SsoClient\Contracts\SsoAuthenticatable;
use UnimontesCead\SsoClient\SsoUser;

class User extends Authenticatable implements SsoAuthenticatable
{
    public static function fromSsoData(SsoUser $ssoUser): static
    {
        return static::updateOrCreate(
            ['sso_id' => $ssoUser->id],
            [
                'name' => $ssoUser->name,
                'email' => $ssoUser->email,
                'cpf' => $ssoUser->cpf,
                'phone' => $ssoUser->phone,
                'avatar_url' => $ssoUser->avatarUrl,
            ],
        );
    }
}

You'll need a sso_id column (string/uuid, unique) on your users table to key that lookup on.

Using roles

$ssoUser->roles is null when this client wasn't granted the role scope, otherwise an array of SsoUserRole. A common pattern is to store the active roles' values directly as your local roles, since the SSO already manages date-ranged role assignment for you:

$roleValues = $ssoUser->roles !== null
    ? array_map(fn (SsoUserRole $role) => $role->value, $ssoUser->roles)
    : [];

$user->roles()->sync($roleValues);

// or a quick membership check, e.g. gating admin-only UI:
if ($ssoUser->hasRole(1)) { /* ... */ }

Logging in

With the built-in routes (default), just link to the redirect route:

<a href="{{ route('sso.redirect') }}">Entrar com o SSO</a>

That's the whole flow — it exchanges the code, fetches /api/user, calls your User::fromSsoData(), logs the user in, and redirects to sso.routes.redirect_after_login.

Logging out

<form method="POST" action="{{ route('sso.logout') }}">
    @csrf
    <button type="submit">Sair</button>
</form>

This ends the local session and redirects the browser to the SSO's own single-logout endpoint (GET /oauth/logout/{client_id} on the SSO), which ends the SSO's session and revokes every OAuth token this user has been issued, then bounces back to this client's registered "URL inicial".

What this does and doesn't do: the SSO won't silently re-authenticate the user anymore, so the next "entrar com o SSO" — in this app or any other — requires fresh credentials. It does not reach into other client apps' already-open local sessions and close them; that would require a back-channel logout protocol (each client exposing its own logout webhook that the SSO calls server-to-server) which this package doesn't implement. For most internal tooling, killing the SSO session is the meaningful "logout everywhere" boundary — treat true simultaneous multi-tab/multi-app session termination as a separate, bigger feature if you need it.

Rolling your own flow

Set SSO_ROUTES_ENABLED=false and drive it yourself:

use Laravel\Socialite\Facades\Socialite;

Route::get('/login/sso', fn () => Socialite::driver('sso')->redirect());

Route::get('/login/sso/callback', function () {
    $ssoUser = Socialite::driver('sso')->user(); // SsoUser instance
    $user = \App\Models\User::fromSsoData($ssoUser);
    auth()->login($user, remember: true);
    return redirect('/');
});

Route::post('/logout/sso', function (\Illuminate\Http\Request $request) {
    auth()->guard('web')->logout();
    $request->session()->invalidate();
    $request->session()->regenerateToken();
    return redirect()->away(
        rtrim(config('sso.base_url'), '/').'/oauth/logout/'.config('sso.client_id'),
    );
});

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-07-10

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固