This commit is contained in:
神楽坂 白 2024-06-10 20:49:23 +08:00
parent d1f6de9007
commit 65225b65a3
7 changed files with 429 additions and 10 deletions

View File

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Auth; namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Coderflex\LaravelTurnstile\Rules\TurnstileCheck;
use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller class LoginController extends Controller
@ -16,7 +17,7 @@ class LoginController extends Controller
| redirecting them to your home screen. The controller uses a trait | redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications. | to conveniently provide its functionality to your applications.
| |
*/ */
use AuthenticatesUsers; use AuthenticatesUsers;
@ -37,4 +38,22 @@ public function __construct()
$this->middleware('guest')->except('logout'); $this->middleware('guest')->except('logout');
$this->middleware('auth')->only('logout'); $this->middleware('auth')->only('logout');
} }
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function validateLogin(Request $request)
{
$request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
'cf-turnstile-response' => ['required', new TurnstileCheck()],
]);
}
} }

View File

@ -4,6 +4,7 @@
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\User; use App\Models\User;
use Coderflex\LaravelTurnstile\Rules\TurnstileCheck;
use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
@ -19,7 +20,7 @@ class RegisterController extends Controller
| validation and creation. By default this controller uses a trait to | validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code. | provide this functionality without requiring any additional code.
| |
*/ */
use RegistersUsers; use RegistersUsers;
@ -49,9 +50,10 @@ public function __construct()
protected function validator(array $data) protected function validator(array $data)
{ {
return Validator::make($data, [ return Validator::make($data, [
'name' => ['required', 'string', 'max:255'], 'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'], 'password' => ['required', 'string', 'min:8', 'confirmed'],
'cf-turnstile-response' => ['required', new TurnstileCheck()],
]); ]);
} }
@ -64,8 +66,8 @@ protected function validator(array $data)
protected function create(array $data) protected function create(array $data)
{ {
return User::create([ return User::create([
'name' => $data['name'], 'name' => $data['name'],
'email' => $data['email'], 'email' => $data['email'],
'password' => Hash::make($data['password']), 'password' => Hash::make($data['password']),
]); ]);
} }

View File

@ -6,6 +6,7 @@
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": "^8.1", "php": "^8.1",
"coderflex/laravel-turnstile": "^2.0",
"guzzlehttp/guzzle": "^7.2", "guzzlehttp/guzzle": "^7.2",
"jeroennoten/laravel-adminlte": "^3.11", "jeroennoten/laravel-adminlte": "^3.11",
"laravel/framework": "^10.10", "laravel/framework": "^10.10",

136
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "a9e39c5d5e9d2a17dcb236298d3cca77", "content-hash": "bb271a22f0d60e284a4d8bda9af25f99",
"packages": [ "packages": [
{ {
"name": "almasaeed2010/adminlte", "name": "almasaeed2010/adminlte",
@ -104,6 +104,80 @@
], ],
"time": "2023-01-15T23:15:59+00:00" "time": "2023-01-15T23:15:59+00:00"
}, },
{
"name": "coderflex/laravel-turnstile",
"version": "v2.0.1",
"source": {
"type": "git",
"url": "https://github.com/coderflexx/laravel-turnstile.git",
"reference": "02d5604e32f9ea578b5a40bc92b97c8b726ca34b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/coderflexx/laravel-turnstile/zipball/02d5604e32f9ea578b5a40bc92b97c8b726ca34b",
"reference": "02d5604e32f9ea578b5a40bc92b97c8b726ca34b",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^7.7",
"illuminate/contracts": "^10.0|^11.0",
"php": "^8.1|^8.2",
"spatie/laravel-package-tools": "^1.14.0"
},
"require-dev": {
"laravel/pint": "^1.0",
"nunomaduro/collision": "^7.0|^8.0",
"nunomaduro/larastan": "^2.0.1",
"orchestra/testbench": "^8.0|^9.0",
"pestphp/pest": "^2.0",
"pestphp/pest-plugin-arch": "^2.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-phpunit": "^1.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Coderflex\\LaravelTurnstile\\LaravelTurnstileServiceProvider"
],
"aliases": {
"LaravelTurnstile": "Coderflex\\LaravelTurnstile\\Facades\\LaravelTurnstile"
}
}
},
"autoload": {
"psr-4": {
"Coderflex\\LaravelTurnstile\\": "src/",
"Coderflex\\LaravelTurnstile\\Database\\Factories\\": "database/factories/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "ousid",
"email": "oussama@coderflex.com",
"role": "Developer"
}
],
"description": "A package to help you implement the Cloudflare turnstile \"CAPTCHA Alternative\"",
"homepage": "https://github.com/coderflexx/laravel-turnstile",
"keywords": [
"cloudflare",
"coderflex",
"laravel",
"laravel-turnstile",
"turnstile"
],
"support": {
"issues": "https://github.com/coderflexx/laravel-turnstile/issues",
"source": "https://github.com/coderflexx/laravel-turnstile/tree/v2.0.1"
},
"time": "2024-04-08T16:05:46+00:00"
},
{ {
"name": "dflydev/dot-access-data", "name": "dflydev/dot-access-data",
"version": "v3.0.2", "version": "v3.0.2",
@ -3461,6 +3535,66 @@
], ],
"time": "2023-04-15T23:01:58+00:00" "time": "2023-04-15T23:01:58+00:00"
}, },
{
"name": "spatie/laravel-package-tools",
"version": "1.16.4",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-package-tools.git",
"reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53",
"reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53",
"shasum": ""
},
"require": {
"illuminate/contracts": "^9.28|^10.0|^11.0",
"php": "^8.0"
},
"require-dev": {
"mockery/mockery": "^1.5",
"orchestra/testbench": "^7.7|^8.0",
"pestphp/pest": "^1.22",
"phpunit/phpunit": "^9.5.24",
"spatie/pest-plugin-test-time": "^1.1"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\LaravelPackageTools\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"role": "Developer"
}
],
"description": "Tools for creating Laravel packages",
"homepage": "https://github.com/spatie/laravel-package-tools",
"keywords": [
"laravel-package-tools",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/laravel-package-tools/issues",
"source": "https://github.com/spatie/laravel-package-tools/tree/1.16.4"
},
"funding": [
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2024-03-20T07:29:11+00:00"
},
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v6.3.4", "version": "v6.3.4",

36
config/turnstile.php Normal file
View File

@ -0,0 +1,36 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Turnstile Keys
|--------------------------------------------------------------------------
|
| This value is the site, and the secret key of your application, after creating an application
| with Cloudflare turnstile, copy the site key, and use it here, or in the .env
| file.
| Note that the secret key should not be publicly accessible.
|
| @see: https://developers.cloudflare.com/turnstile/get-started/#get-a-sitekey-and-secret-key
|
*/
'turnstile_site_key' => env('TURNSTILE_SITE_KEY', null),
'turnstile_secret_key' => env('TURNSTILE_SECRET_KEY', null),
/*
|--------------------------------------------------------------------------
| Error Messages
|--------------------------------------------------------------------------
|
| Here you can find the error messages for the application. You can modify
| or translate the error message as you like.
|
| Note that you can translate the error message directly, without wrapping
| them in translate helper.
|
*/
'error_messages' => [
'turnstile_check_message' => 'The CAPTCHA thinks you are a robot! Please refresh and try again.',
],
];

View File

@ -1 +1,113 @@
@extends('adminlte::auth.login') @extends('adminlte::auth.auth-page', ['auth_type' => 'login'])
@section('adminlte_css_pre')
<link rel="stylesheet" href="{{ asset('vendor/icheck-bootstrap/icheck-bootstrap.min.css') }}">
@stop
@php( $login_url = View::getSection('login_url') ?? config('adminlte.login_url', 'login') )
@php( $register_url = View::getSection('register_url') ?? config('adminlte.register_url', 'register') )
@php( $password_reset_url = View::getSection('password_reset_url') ?? config('adminlte.password_reset_url', 'password/reset') )
@if (config('adminlte.use_route_url', false))
@php( $login_url = $login_url ? route($login_url) : '' )
@php( $register_url = $register_url ? route($register_url) : '' )
@php( $password_reset_url = $password_reset_url ? route($password_reset_url) : '' )
@else
@php( $login_url = $login_url ? url($login_url) : '' )
@php( $register_url = $register_url ? url($register_url) : '' )
@php( $password_reset_url = $password_reset_url ? url($password_reset_url) : '' )
@endif
@section('auth_header', __('adminlte::adminlte.login_message'))
@section('auth_body')
<form action="{{ $login_url }}" method="post">
@csrf
{{-- Email field --}}
<div class="input-group mb-3">
<input type="email" name="email" class="form-control @error('email') is-invalid @enderror"
value="{{ old('email') }}" placeholder="{{ __('adminlte::adminlte.email') }}" autofocus>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope {{ config('adminlte.classes_auth_icon', '') }}"></span>
</div>
</div>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
{{-- Password field --}}
<div class="input-group mb-3">
<input type="password" name="password" class="form-control @error('password') is-invalid @enderror"
placeholder="{{ __('adminlte::adminlte.password') }}">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock {{ config('adminlte.classes_auth_icon', '') }}"></span>
</div>
</div>
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="input-group mb-3">
<x-turnstile-widget theme="auto"/>
@error('cf-turnstile-response')
<span class="invalid-feedback" style="display: block;" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
{{-- Login field --}}
<div class="row">
<div class="col-7">
<div class="icheck-primary" title="{{ __('adminlte::adminlte.remember_me_hint') }}">
<input type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label for="remember">
{{ __('adminlte::adminlte.remember_me') }}
</label>
</div>
</div>
<div class="col-5">
<button type=submit class="btn btn-block {{ config('adminlte.classes_auth_btn', 'btn-flat btn-primary') }}">
<span class="fas fa-sign-in-alt"></span>
{{ __('adminlte::adminlte.sign_in') }}
</button>
</div>
</div>
</form>
@stop
@section('auth_footer')
{{-- Password reset link --}}
@if($password_reset_url)
<p class="my-0">
<a href="{{ $password_reset_url }}">
{{ __('adminlte::adminlte.i_forgot_my_password') }}
</a>
</p>
@endif
{{-- Register link --}}
@if($register_url)
<p class="my-0">
<a href="{{ $register_url }}">
{{ __('adminlte::adminlte.register_a_new_membership') }}
</a>
</p>
@endif
@stop

View File

@ -1 +1,116 @@
@extends('adminlte::auth.register') @extends('adminlte::auth.auth-page', ['auth_type' => 'register'])
@php( $login_url = View::getSection('login_url') ?? config('adminlte.login_url', 'login') )
@php( $register_url = View::getSection('register_url') ?? config('adminlte.register_url', 'register') )
@if (config('adminlte.use_route_url', false))
@php( $login_url = $login_url ? route($login_url) : '' )
@php( $register_url = $register_url ? route($register_url) : '' )
@else
@php( $login_url = $login_url ? url($login_url) : '' )
@php( $register_url = $register_url ? url($register_url) : '' )
@endif
@section('auth_header', __('adminlte::adminlte.register_message'))
@section('auth_body')
<form action="{{ $register_url }}" method="post">
@csrf
{{-- Name field --}}
<div class="input-group mb-3">
<input type="text" name="name" class="form-control @error('name') is-invalid @enderror"
value="{{ old('name') }}" placeholder="{{ __('adminlte::adminlte.full_name') }}" autofocus>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-user {{ config('adminlte.classes_auth_icon', '') }}"></span>
</div>
</div>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
{{-- Email field --}}
<div class="input-group mb-3">
<input type="email" name="email" class="form-control @error('email') is-invalid @enderror"
value="{{ old('email') }}" placeholder="{{ __('adminlte::adminlte.email') }}">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope {{ config('adminlte.classes_auth_icon', '') }}"></span>
</div>
</div>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
{{-- Password field --}}
<div class="input-group mb-3">
<input type="password" name="password" class="form-control @error('password') is-invalid @enderror"
placeholder="{{ __('adminlte::adminlte.password') }}">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock {{ config('adminlte.classes_auth_icon', '') }}"></span>
</div>
</div>
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
{{-- Confirm password field --}}
<div class="input-group mb-3">
<input type="password" name="password_confirmation"
class="form-control @error('password_confirmation') is-invalid @enderror"
placeholder="{{ __('adminlte::adminlte.retype_password') }}">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock {{ config('adminlte.classes_auth_icon', '') }}"></span>
</div>
</div>
@error('password_confirmation')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="input-group mb-3">
<x-turnstile-widget theme="auto"/>
@error('cf-turnstile-response')
<span class="invalid-feedback" style="display: block;" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
{{-- Register button --}}
<button type="submit" class="btn btn-block {{ config('adminlte.classes_auth_btn', 'btn-flat btn-primary') }}">
<span class="fas fa-user-plus"></span>
{{ __('adminlte::adminlte.register') }}
</button>
</form>
@stop
@section('auth_footer')
<p class="my-0">
<a href="{{ $login_url }}">
{{ __('adminlte::adminlte.i_already_have_a_membership') }}
</a>
</p>
@stop