如何基于Laravel搭建简易CAS Server单点登录服务端
基于Laravel搭建简易CAS Server实现方案
subfission/cas 是标准CAS协议客户端实现,没有专属绑定的服务端要求,只要实现CAS 3.0核心接口即可完成对接,不需要部署完整的重型Apereo CAS服务,简易场景仅需以下步骤即可跑通流程:
前置准备
- 新建独立Laravel项目作为CAS服务端,可与现有客户端项目同域部署,注意做好cookie路径隔离即可。
- 完成基础数据库配置,直接使用Laravel自带的
users表作为用户存储表即可。 - 执行以下命令生成基础登录认证脚手架,先跑通服务端自身的账号登录、退出流程:
composer require laravel/ui php artisan ui bootstrap --auth php artisan migrate npm install && npm run build
核心配置与数据结构
- 新建服务端CAS配置文件
config/cas.php,配置允许接入的客户端白名单与票据有效期:<?php return [ // 允许接入的客户端回调地址列表 'allowed_services' => [ 'http://your-client-app.test/cas/callback', ], // 临时授权票据有效期(秒) 'ticket_expire' => 300, ]; - 生成票据存储模型与迁移表,用来存储登录后颁发的临时授权票据:
执行命令php artisan make:model CasTicket -m,编辑对应迁移文件的up方法:
执行Schema::create('cas_tickets', function (Blueprint $table) { $table->id(); $table->string('ticket', 64)->unique()->index(); $table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->string('service_url')->index(); $table->timestamp('expired_at'); $table->timestamps(); });php artisan migrate完成建表,在App/Models/CasTicket.php中添加批量赋值配置即可。
核心接口实现
CAS协议核心仅需3个接口即可完成基础单点登录能力,在routes/web.php中注册路由(注意仅保留会话启动中间件,不要叠加额外权限拦截):
use App\Http\Controllers\CasServerController; Route::get('/cas/login', [CasServerController::class, 'login']); Route::get('/cas/p3/serviceValidate', [CasServerController::class, 'validate']); Route::get('/cas/logout', [CasServerController::class, 'logout']);
对应控制器逻辑如下:
- 登录接口(/cas/login):
接收客户端传入的service参数(客户端回调地址),首先校验该地址是否在配置的白名单内,不在直接返回403。
校验当前用户是否已有服务端登录态:- 已登录:生成
ST-前缀的32位随机字符串作为授权票据,存入cas_tickets表关联当前用户ID、对应service地址、过期时间,之后302跳转至{service}?ticket={生成的票据}即可。 - 未登录:跳转至服务端自带的登录页面,用户完成账号密码校验登录成功后,再执行上述票据生成、跳转逻辑。
- 已登录:生成
- 票据校验接口(/cas/p3/serviceValidate):
接收传入的service、ticket参数,查询数据库中是否存在对应票据、service地址匹配、未过期的记录:- 校验通过:删除该票据(避免重复使用),返回XML格式的认证成功响应,可按需携带用户ID、用户名、邮箱等属性字段。
- 校验不通过:返回XML格式的认证失败响应,标注错误原因。
响应格式参考:
<!-- 认证成功 --> <cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas"> <cas:authenticationSuccess> <cas:user>用户唯一标识(如邮箱/用户ID)</cas:user> </cas:authenticationSuccess> </cas:serviceResponse> <!-- 认证失败 --> <cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas"> <cas:authenticationFailure code="INVALID_TICKET">票据无效或已过期</cas:authenticationFailure> </cas:serviceResponse> - 登出接口(/cas/logout):
清除当前用户的服务端登录会话,若请求携带了合法的service参数则跳转至对应地址,否则返回登出成功提示即可。
客户端对接
修改现有subfission/cas客户端的配置文件,将CAS服务端地址、登录地址、校验地址、登出地址分别替换为你刚搭建的服务端对应路径,其余配置保持原有规则不变,即可完成对接测试。
该实现仅覆盖CAS核心流程,适用于本地开发、内部小系统场景;若要用于公网生产环境,需额外补充HTTPS强制、请求签名校验、票据防重放、跨域安全策略等防护逻辑。
内容的提问来源于stack exchange,提问作者Mostafa Lotfi
相关产品推荐
相关产品推荐

