rizalrepo / sso-client
SSO 客户端 OAuth 2.0
1.3.0
2024-08-22 07:15 UTC
Requires
- php: ^7.4|^8.0
Requires (Dev)
- php: ^7.4|^8.0
This package is auto-updated.
Last update: 2024-09-22 07:33:18 UTC
README
#安装
composer require rizalrepo/sso-client
配置
使用运行命令发布SSOController
php artisan vendor:publish --tag=sso-config
连接SSO
打开config/sso.php并根据自己的喜好调整配置
return [
'callbackUrl' => "http://127.0.0.1:8000/callback",
'serverUrl' => "http://127.0.0.1:8081",
'clientId' => "f9c2bbad-c06d-4028-9786-213c9113ddbb",
'clientSecret' => "1zJyzTcLmL05ZzMOnaMI6DfhaY9guJLCKBisH4YS",
];
路由
将代码添加到web.php
Route::controller(SSOController::class)->group(function () {
Route::get("/", 'ssoPage');
Route::get("/sso/login", 'getLogin')->name("sso.login");
Route::get("/callback", 'getCallback')->name("sso.callback");
Route::get("/sso/connect", 'connectUser')->name("sso.connect");
Route::middleware('auth')->group(function () {
Route::get("/sso/logout", 'logout')->name("sso.logout");
Route::get("/sso/edit-password", 'editPassword')->name("sso.edit-password");
Route::get("/sso/portal", 'portal')->name("sso.portal");
Route::get("/sso/profile", 'editProfile')->name("sso.profile");
});
});
表
使用以下代码修改文件users migration
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('username')->unique();
$table->string('phone')->unique();
$table->char('prodi', 5)->nullable();
$table->bigInteger('oauth_client_role_id');
$table->timestamp('email_verified_at')->nullable();
$table->rememberToken();
$table->timestamps();
});
中间件设置
- 对于Laravel 11,添加命令
php artisan make:middleware Authenticate
- 然后更新以下代码到Middleware/Authenticate.php,并根据您的喜好调整配置
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
class Authenticate extends Middleware
{
private function getConfig($configName)
{
switch ($configName) {
case 'serverUrl':
return "http://127.0.0.1:8000/login";
default:
return null;
}
}
protected function redirectTo(Request $request): ?string
{
return $request->expectsJson() ? null : $this->getConfig('serverUrl');
}
}
- 然后将以下代码复制到文件bootstrap/app.php
$middleware->alias(['auth' => Authenticate::class]);
- 对于Laravel 10:更新以下代码到Middleware/Authenticate.php,并根据您的喜好调整配置
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
class Authenticate extends Middleware
{
private function getConfig($configName)
{
switch ($configName) {
case 'serverUrl':
return "http://127.0.0.1:8000/login";
default:
return null;
}
}
protected function redirectTo(Request $request): ?string
{
return $request->expectsJson() ? null : $this->getConfig('serverUrl');
}
}
视图配置
- 使用以下代码来显示用户头像、直接访问门户、更新个人资料、编辑密码和注销
{{-- in app blade --}}
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<img class="b-r-10 avatar-image" src="{{ session('avatar') }}" alt="Logo">
@if(session()->has('countAccess'))
@if (session('countAccess') > 1)
<a class="dropdown-item" href="{{ route('sso.portal') }}">Portal</a>
@endif
@endif
<a href="{{ route('sso.profile') }}" onclick="saveReferrer()"><i class="fas fa-user-edit me-2"></i><span>Edit Profile</span></a>
<a class="dropdown-item" href="{{ route('sso.edit-password') }}" onclick="saveReferrer()">
Edit Password
</a>
<a class="dropdown-item" href="{{ route('sso.logout') }}"
onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('sso.logout') }}" method="GET" class="d-none">
@csrf
</form>
</div>
{{-- previous url config in js.blade --}}
<script>
function saveReferrer() {
var previousUrl = document.referrer;
var previousUrlInput = document.getElementById("previous_url");
if (previousUrlInput) {
previousUrlInput.value = previousUrl;
}
}
</script>
客户端的用户控制器
- 用户创建后,将此代码添加到store函数中
$ssoController = new \App\Http\Controllers\SSO\SSOController();
$userArray = [
'name' => $user->name,
'username' => $user->username,
'phone' => $user->phone,
'oauth_client_role_id' => $user->oauth_client_role_id,
];
$ssoController->createUserOnServer($userArray);
- 用户更新后,将此代码添加到update函数中
$oldUsername = $user->username; // this code add before update()
$updatedUserArray = [
'name' => $user->name,
'username' => $user->username,
'phone' => $user->phone,
'old_username' => $oldUsername,
];
$ssoController = new \App\Http\Controllers\SSO\SSOController();
$ssoController->updateUserOnServer($updatedUserArray);
- 用户删除后,将此代码添加到destroy函数中
$username = $data->username; // this code add before delete()
$ssoController = new \App\Http\Controllers\SSO\SSOController();
$ssoController->deleteUserOnServer($username);
从客户端验证API令牌
- 使用运行命令创建新的中间件
php artisan make:middleware VerifyApiToken
- 然后打开文件VerifyApiToken,并用以下代码替换
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class VerifyApiToken
{
public function handle($request, Closure $next)
{
$token = $request->bearerToken();
if (!$token) {
Log::warning('No bearer token provided and no access token in session');
return response()->json(['error' => 'Unauthorized'], 401);
}
try {
$serverUrl = Config::get('sso.serverUrl');
$response = Http::timeout(5)->withHeaders([
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
])->get($serverUrl . '/api/verify-token');
if ($response->successful()) {
$request->merge(['sso_user' => $response->json()]);
return $next($request);
}
return response()->json(['error' => 'Invalid token'], 401);
} catch (\Exception $e) {
return response()->json(['error' => 'Error verifying token'], 500);
}
}
}
- 为Laravel 10添加中间件别名到Kernel.php,或为Laravel 11添加到bootstrap/app.php
'verify.api.token' => \App\Http\Middleware\VerifyApiToken::class,