ikechukwukalu / sanctumauthstarter
Laravel sanctum auth starter
Requires
- php: ^8.0
- beyondcode/laravel-websockets: ^1.14
- doctrine/dbal: ^3.5
- hisorange/browser-detect: ^4.5
- illuminate/auth: ^9.0|^10.0
- illuminate/broadcasting: ^9.0|^10.0
- illuminate/bus: ^9.0|^10.0
- illuminate/contracts: ^9.0|^10.0
- illuminate/database: ^9.0|^10.0
- illuminate/events: ^9.0|^10.0
- illuminate/http: ^9.0|^10.0
- illuminate/notifications: ^9.0|^10.0
- illuminate/queue: ^9.0|^10.0
- illuminate/routing: ^9.0|^10.0
- illuminate/support: ^9.0|^10.0
- illuminate/validation: ^9.0|^10.0
- illuminate/view: ^9.0|^10.0
- laragear/two-factor: ^1.2
- laravel/sanctum: ^3.0
- laravel/socialite: ^5.5
- laravel/ui: ^4.0
- nesbot/carbon: ^2.67
- predis/predis: ^2.1
- pusher/pusher-php-server: ^7.2
- stevebauman/location: ^6.6
- symfony/console: ^6.0
- symfony/finder: ^6.0
Requires (Dev)
- knuckleswtf/scribe: dev-master
- mockery/mockery: ^1.4.4
- orchestra/testbench: ^7.0|^8.0
- php-parallel-lint/php-parallel-lint: dev-develop
- phpunit/phpunit: ^9.0|^10.0
README
这是一个非常灵活且可定制的 Laravel 包(模板),利用 laravel/ui 和 laravel-sanctum 来创建基本认证类和其他有助于快速开始构建 REST API 的功能。以下功能可供使用:
- 用户注册
- 用户登录
- 注册后自动登录
- 登录节流
- 登录双因素认证
- 社交媒体登录
- 忘记密码
- 电子邮件验证
- 重新发送电子邮件验证
- 重置密码
- 更改密码
- 编辑用户资料
- 通知
- 欢迎通知
- 电子邮件验证
- 登录通知
- 密码更改通知
- 生成文档
- GitHub 的辅助 CI/CD 文件
需求
- PHP 8+
- Laravel 9+
安装步骤
composer require ikechukwukalu/sanctumauthstarter
php artisan ui bootstrap
npm install --save-dev laravel-echo pusher-js
- 在
User
模型类中取消注释use Illuminate\Contracts\Auth\MustVerifyEmail;
- 在
User
模型类中将two_factor
列添加到fillable
和hidden
数组中。最终User
应该看起来像这样
use Laravel\Sanctum\HasApiTokens; use Laragear\TwoFactor\TwoFactorAuthentication; use Laragear\TwoFactor\Contracts\TwoFactorAuthenticatable; class User extends Authenticatable implements TwoFactorAuthenticatable, MustVerifyEmail { use HasApiTokens, HasFactory, Notifiable, TwoFactorAuthentication; /** * The attributes that are mass assignable. * * @var array<int, string> */ protected $fillable = [ 'name', 'email', 'password', 'two_factor', 'socialite_signup', 'form_signup' ]; /** * The attributes that should be hidden for serialization. * * @var array<int, string> */ protected $hidden = [ 'password', 'remember_token', 'two_factor', ]; /** * The attributes that should be cast. * * @var array<string, string> */ protected $casts = [ 'email_verified_at' => 'datetime', ]; }
生成认证控制器、请求、服务和路由
您可以通过运行 php artisan sas:setup
一次性生成它们。您也可以单独生成它们
php artisan sas:controllers
php artisan sas:routes
php artisan sas:tests
发布迁移和配置
php artisan vendor:publish --tag=sas-migrations
php artisan vendor:publish --tag=sas-config
WEBSOCKETS 和 QUEUE
此包利用 Laravel beyondcode/laravel-websockets 在认证后向客户端传递 access_token
。首先,您必须设置您的 Laravel 应用以进行广播。为此,请运行以下命令:
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"
- 在您的
.env
文件中设置REDIS_CLIENT=predis
和BROADCAST_DRIVER=pusher
。 - 您的
laravel-echo
配置应类似于以下内容
window.Echo = new Echo({ broadcaster: 'pusher', key: import.meta.env.VITE_PUSHER_APP_KEY, wsHost: window.location.hostname, wsPort: 6001, forceTLS: false, encrypted: false, enabledTransports: ['ws', 'wss'], disableStats: true, cluster:import.meta.env.VITE_PUSHER_APP_CLUSTER, authorizer: (channel, options) => { return { authorize: (socketId, callback) => { axios.post('/broadcasting/auth', { socket_id: socketId, channel_name: channel.name }) .then(response => { callback(false, response.data); }) .catch(error => { callback(true, error); }); } }; }, });
您需要一个 队列 工作员来处理通知和其他事件。
- 在您的
.env
文件中设置QUEUE_CONNECTION=redis
。 - 在
config/app.php
中取消注释App\Providers\BroadcastServiceProvider::class
- 您的
.env
应该类似于以下内容
PUSHER_APP_KEY=app-key PUSHER_APP_ID=app-id PUSHER_APP_SECRET=app-secret PUSHER_HOST=127.0.0.1 PUSHER_PORT=6001 PUSHER_SCHEME=http PUSHER_APP_CLUSTER=mt1
- 对于使用 Apache 的 SSL,以下片段应放置在
virtualhost
SSL 配置中。
ProxyPass "/app/" "ws://127.0.0.1:6001/app/" ProxyPass "/app/" "http://127.0.0.1:6001/app/"
- 运行
php artisan config:clear
、php artisan migrate
、php artisan websockets:serve
和php artisan queue:work
php artisan serve
npm install && npm run dev
WEBVIEW 登录
- 社交媒体登录
- 双因素登录
社交媒体登录
将以下内容添加到您的 config/services.php
文件中。
'google' => [ 'client_id' => env('GOOGLE_CLIENT_ID'), 'client_secret' => env('GOOGLE_CLIENT_SECRET'), 'redirect' => env('GOOGLE_CLIENT_REDIRECT'), ],
- 导航到
auth/socialite
以查看生成的access_token
后的示例 Google 注册/登录页面。取消注释web.php
中的路由。以下是在视图resources/views/vendor/sanctumauthstarter/socialite/auth.blade.php
中调用的脚本。
window.addEventListener('DOMContentLoaded', () => { const getUserUUID = () => { let userUUID = localStorage.getItem('user_uuid'); if (!userUUID) { userUUID = crypto.randomUUID(); localStorage.setItem('user_uuid', userUUID); } console.log('user_uuid created', userUUID); return userUUID; } const removeUserUUID = () => { if (localStorage.getItem('user_uuid')) { localStorage.removeItem('user_uuid'); } console.log('user_uuid removed'); } const USER_UUID = getUserUUID(); const TIMEOUT = parseInt("{{ $minutes }}") * 60 * 1000; window.Echo.channel(`access.token.socialite.${USER_UUID}`) .listen('.Ikechukwukalu\\Sanctumauthstarter\\Events\\SocialiteLogin', (e) => { console.log(`payload:`, e); }); document.getElementById('googleSignUp').onclick = () => { window.open( "{{ url('auth/redirect') }}/" + USER_UUID, '_blank' ) } setTimeout(() => { removeUserUUID(); }, TIMEOUT); });
- 认证成功后,此视图显示在
resources/views/vendor/sanctumauthstarter/socialite/callback.blade.php
,其中包含以下脚本
window.addEventListener('DOMContentLoaded', () => { if (localStorage.getItem('user_uuid')) { localStorage.removeItem('user_uuid'); } });
双因素登录
该软件包利用 Laragear/TwoFactor 来启用双因素认证登录,并使用 beyondcode/laravel-websockets 在认证后向客户端传递 access_token
。
已为密码登录和社交媒体登录实现了双因素认证。
php artisan vendor:publish --provider="Laragear\TwoFactor\TwoFactorServiceProvider"
php artisan migrate
- 将
resources/views/vendor/two-factor/login.blade.php
中的表单替换为以下代码
<form method="get"> @php foreach ($_GET as $key => $value) { $key = htmlspecialchars($key); $value = htmlspecialchars($value); echo "<input type='hidden' name='$key' value='$value'/>"; } @endphp @csrf <p class="text-center"> {{ trans('two-factor::messages.continue') }} </p> <div class="form-row justify-content-center py-3"> @if($errors->isNotEmpty() || isset($message)) <div class="col-12 alert alert-danger pb-0"> <ul> @if (isset($message)) <li>{{ $message }}</li> @endif @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <div class="col-sm-8 col-8 mb-3"> <input type="text" name="{{ $input }}" id="{{ $input }}" class="@error($input) is-invalid @enderror form-control form-control-lg" minlength="6" placeholder="123456" required> </div> <div class="w-100"></div> <div class="col-auto mb-3"> <button type="submit" class="btn btn-primary btn-lg"> {{ trans('two-factor::messages.confirm') }} </button> </div> </div> </form>
- 调用
api/create-two-factor
来创建双因素认证。
{ "status": "success", "status_code": 200, "data": { "qr_code": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg...", "uri": "otpauth://totp/%3Ajohndoe@xyz.com?label=johndoe%40xyz.com&secret=EQGRSNGAE3TREOT7XOLB5VVRS42LLXYS&algorithm=SHA1&digits=6", "string": "EQGRSNGAE3TREOT7XOLB5VVRS42LLXYS" } }
- 调用
api/confirm-two-factor
来确认双因素认证并获得恢复码。
{ "status": "success", "status_code": 200, "data": { "message": "Download your recover codes and keep them safe!", "codes": [ { "code": "SV6OH71D", "used_at": null }, { "code": "62KEBSNE", "used_at": null }, { "code": "YSVHOG9X", "used_at": null }, ... ] } }
- 调用
api/disable-two-factor
来禁用双因素认证,调用api/current-recovery-codes
来检索当前恢复码,调用api/new-recovery-codes
来生成新的恢复码,这将替换之前的批次。
为密码登录启用双因素认证
当双因素认证已启用且用户尝试登录时,将返回一个包含 user_uuid
和 twofactor_url
的负载。
{ "status": "success", "status_code": 200, "data": { "twofactor_url": "http://127.0.0.1:8000/twofactor/required/johndoe@xyz.com/0220dbe7-08dc-470e-b1e2-4411ba155bc1", "user_uuid": "0220dbe7-08dc-470e-b1e2-4411ba155bc1", "access_token": null, "message": "Two-Factor Authentication is required!" } }
使用 user_uuid
创建一个将监听 Laravel 广播的 laravel-echo
通道。导航到 auth/twofactor/{email}/{uuid}
来查看在 web.php
中取消注释路由后的生成的 access_token
。此视图 resources/views/vendor/sanctumauthstarter/twofactor/auth.blade.php
包含一个示例 javascript
代码,用于实现这一功能。
window.addEventListener('DOMContentLoaded', () => { const USER_UUID = "{{ Route::input('uuid') }}"; console.log(USER_UUID); window.Echo.channel(`access.token.twofactor.${USER_UUID}`) .listen('.Ikechukwukalu\\Sanctumauthstarter\\Events\\TwoFactorLogin', (e) => { console.log(`payload:`, e); }); });
为社交媒体登录启用双因素认证
当双因素认证已启用时,将在您的浏览器中弹出双因素认证页面。
文档
要生成文档
composer require --dev knuckleswtf/scribe
php artisan vendor:publish --tag=scribe-config
- 如果您想看到
web.php
的 API 文档,请将'prefixes' => ['api/*']
更改为'prefixes' => ['*']
。 php artisan scribe:generate
访问您新生成的文档
- 如果您使用的是
static
类型,请找到您public/
文件夹中的docs/index.html
文件并在浏览器中打开它。 - 如果您使用的是
laravel
类型,请启动您的应用程序(php artisan serve
),然后访问/docs
。
example_languages
:对于每个端点,都会在数组中指定的每种语言中显示一个示例请求。目前,只包括 bash
(curl)、javascript
(Fetch)、php
(Guzzle)和 python
(requests)。您可以添加更多语言,但您还必须创建相应的 Blade 视图(查看添加更多示例语言)。
默认:["bash", "javascript"]
请访问 scribe 了解更多详情。
测试
建议您在开始添加自定义模型和控制器之前运行测试。确保将 database/factories/UserFactory.php
类更新为与您的 users
表匹配,以便测试可以继续成功运行。
密码
在 database/factories/UserFactory.php
类中创建的密码必须与以下验证匹配
'password' => ['required', 'string', 'max:16', Password::min(8) ->letters()->mixedCase() ->numbers()->symbols() ->uncompromised(),
运行测试
php artisan test
推荐软件包
composer require ikechukwukalu/makeservice
composer require ikechukwukalu/databasebackup
composer require ikechukwukalu/requirepin
composer require ikechukwukalu/clamavfileupload
发布视图
php artisan vendor:publish --tag=sas-views
发布语言
php artisan vendor:publish --tag=sas-lang
发布 Laravel 邮件通知 Blade
php artisan vendor:publish --tag=laravel-notifications
发布 GitHub 工作流程
php artisan vendor:publish --tag=github
许可证
SAS软件包是一个开源软件,根据MIT许可证授权。