diff --git a/config/catch.php b/config/catch.php deleted file mode 100644 index 1219ed7..0000000 --- a/config/catch.php +++ /dev/null @@ -1,151 +0,0 @@ - [ - - ], - - /* - |-------------------------------------------------------------------------- - | catch-admin catch_auth_middleware_alias - |-------------------------------------------------------------------------- - | - | where you can set default middlewares - | - */ - 'catch_auth_middleware_alias' => [ - - ], - - /* - |-------------------------------------------------------------------------- - | catch-admin super admin id - |-------------------------------------------------------------------------- - | - | where you can set super admin id - | - */ - 'super_admin' => 1, - - /* - |-------------------------------------------------------------------------- - | catch-admin module setting - |-------------------------------------------------------------------------- - | - | the root where module generate - | the namespace is module root namespace - | the default dirs is module generate default dirs - */ - 'module' => [ - 'root' => 'modules', - - 'namespace' => 'Modules', - - 'default' => ['develop', 'user', 'permission'], - - 'default_dirs' => [ - 'Http'.DIRECTORY_SEPARATOR, - - 'Http'.DIRECTORY_SEPARATOR.'Requests'.DIRECTORY_SEPARATOR, - - 'Http'.DIRECTORY_SEPARATOR.'Controllers'.DIRECTORY_SEPARATOR, - - 'Models'.DIRECTORY_SEPARATOR, - - 'views'.DIRECTORY_SEPARATOR, - ], - - // storage module information - // which driver should be used? - 'driver' => [ - // currently, catchadmin support file and database - // the default is driver - 'default' => 'file', - - // use database driver - 'table_name' => 'admin_modules' - ], - - /** - * module routes collection - * - */ - 'routes' => [], - ], - - /* - |-------------------------------------------------------------------------- - | catch-admin response - |-------------------------------------------------------------------------- - */ - 'response' => [ - // it's a controller middleware, it's set in CatchController - // if you not need json response, don't extend CatchController - 'always_json' => \Catch\Middleware\JsonResponseMiddleware::class, - - // response listener - // it listens [RequestHandled] event, if you don't need this - // you can change this config - 'request_handled_listener' => \Catch\Listeners\RequestHandledListener::class - ], - - /* - |-------------------------------------------------------------------------- - | catch-admin auth setting - |-------------------------------------------------------------------------- - */ - 'auth' => [ - 'guards' => [ - 'admin' => [ - 'driver' => 'jwt', - 'provider' => 'admin_users', - ], - ], - - 'providers' => [ - 'admin_users' => [ - 'driver' => 'eloquent', - 'model' => \Modules\User\Models\User::class - ] - ] - ], - - /* - |-------------------------------------------------------------------------- - | database sql log - |-------------------------------------------------------------------------- - */ - 'listen_db_log' => true, - - /* - |-------------------------------------------------------------------------- - | route config - |-------------------------------------------------------------------------- - */ - 'route' => [ - 'prefix' => 'api', - - 'middlewares' => [ - \Catch\Middleware\AuthMiddleware::class, - \Catch\Middleware\JsonResponseMiddleware::class - ] - ], -]; diff --git a/config/jwt.php b/config/jwt.php deleted file mode 100644 index 99e3ca1..0000000 --- a/config/jwt.php +++ /dev/null @@ -1,301 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -return [ - - /* - |-------------------------------------------------------------------------- - | JWT Authentication Secret - |-------------------------------------------------------------------------- - | - | Don't forget to set this in your .env file, as it will be used to sign - | your tokens. A helper command is provided for this: - | `php artisan jwt:secret` - | - | Note: This will be used for Symmetric algorithms only (HMAC), - | since RSA and ECDSA use a private/public key combo (See below). - | - */ - - 'secret' => env('JWT_SECRET'), - - /* - |-------------------------------------------------------------------------- - | JWT Authentication Keys - |-------------------------------------------------------------------------- - | - | The algorithm you are using, will determine whether your tokens are - | signed with a random string (defined in `JWT_SECRET`) or using the - | following public & private keys. - | - | Symmetric Algorithms: - | HS256, HS384 & HS512 will use `JWT_SECRET`. - | - | Asymmetric Algorithms: - | RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below. - | - */ - - 'keys' => [ - - /* - |-------------------------------------------------------------------------- - | Public Key - |-------------------------------------------------------------------------- - | - | A path or resource to your public key. - | - | E.g. 'file://path/to/public/key' - | - */ - - 'public' => env('JWT_PUBLIC_KEY'), - - /* - |-------------------------------------------------------------------------- - | Private Key - |-------------------------------------------------------------------------- - | - | A path or resource to your private key. - | - | E.g. 'file://path/to/private/key' - | - */ - - 'private' => env('JWT_PRIVATE_KEY'), - - /* - |-------------------------------------------------------------------------- - | Passphrase - |-------------------------------------------------------------------------- - | - | The passphrase for your private key. Can be null if none set. - | - */ - - 'passphrase' => env('JWT_PASSPHRASE'), - - ], - - /* - |-------------------------------------------------------------------------- - | JWT time to live - |-------------------------------------------------------------------------- - | - | Specify the length of time (in minutes) that the token will be valid for. - | Defaults to 1 hour. - | - | You can also set this to null, to yield a never expiring token. - | Some people may want this behaviour for e.g. a mobile app. - | This is not particularly recommended, so make sure you have appropriate - | systems in place to revoke the token if necessary. - | Notice: If you set this to null you should remove 'exp' element from 'required_claims' list. - | - */ - - 'ttl' => env('JWT_TTL', 30 * 24 * 3600), - - /* - |-------------------------------------------------------------------------- - | Refresh time to live - |-------------------------------------------------------------------------- - | - | Specify the length of time (in minutes) that the token can be refreshed - | within. I.E. The user can refresh their token within a 2 week window of - | the original token being created until they must re-authenticate. - | Defaults to 2 weeks. - | - | You can also set this to null, to yield an infinite refresh time. - | Some may want this instead of never expiring tokens for e.g. a mobile app. - | This is not particularly recommended, so make sure you have appropriate - | systems in place to revoke the token if necessary. - | - */ - - 'refresh_ttl' => env('JWT_REFRESH_TTL', 20160), - - /* - |-------------------------------------------------------------------------- - | JWT hashing algorithm - |-------------------------------------------------------------------------- - | - | Specify the hashing algorithm that will be used to sign the token. - | - */ - - 'algo' => env('JWT_ALGO', Tymon\JWTAuth\Providers\JWT\Provider::ALGO_HS256), - - /* - |-------------------------------------------------------------------------- - | Required Claims - |-------------------------------------------------------------------------- - | - | Specify the required claims that must exist in any token. - | A TokenInvalidException will be thrown if any of these claims are not - | present in the payload. - | - */ - - 'required_claims' => [ - 'iss', - 'iat', - 'exp', - 'nbf', - 'sub', - 'jti', - ], - - /* - |-------------------------------------------------------------------------- - | Persistent Claims - |-------------------------------------------------------------------------- - | - | Specify the claim keys to be persisted when refreshing a token. - | `sub` and `iat` will automatically be persisted, in - | addition to the these claims. - | - | Note: If a claim does not exist then it will be ignored. - | - */ - - 'persistent_claims' => [ - // 'foo', - // 'bar', - ], - - /* - |-------------------------------------------------------------------------- - | Lock Subject - |-------------------------------------------------------------------------- - | - | This will determine whether a `prv` claim is automatically added to - | the token. The purpose of this is to ensure that if you have multiple - | authentication models e.g. `App\User` & `App\OtherPerson`, then we - | should prevent one authentication request from impersonating another, - | if 2 tokens happen to have the same id across the 2 different models. - | - | Under specific circumstances, you may want to disable this behaviour - | e.g. if you only have one authentication model, then you would save - | a little on token size. - | - */ - - 'lock_subject' => true, - - /* - |-------------------------------------------------------------------------- - | Leeway - |-------------------------------------------------------------------------- - | - | This property gives the jwt timestamp claims some "leeway". - | Meaning that if you have any unavoidable slight clock skew on - | any of your servers then this will afford you some level of cushioning. - | - | This applies to the claims `iat`, `nbf` and `exp`. - | - | Specify in seconds - only if you know you need it. - | - */ - - 'leeway' => env('JWT_LEEWAY', 0), - - /* - |-------------------------------------------------------------------------- - | Blacklist Enabled - |-------------------------------------------------------------------------- - | - | In order to invalidate tokens, you must have the blacklist enabled. - | If you do not want or need this functionality, then set this to false. - | - */ - - 'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true), - - /* - | ------------------------------------------------------------------------- - | Blacklist Grace Period - | ------------------------------------------------------------------------- - | - | When multiple concurrent requests are made with the same JWT, - | it is possible that some of them fail, due to token regeneration - | on every request. - | - | Set grace period in seconds to prevent parallel request failure. - | - */ - - 'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0), - - /* - |-------------------------------------------------------------------------- - | Cookies encryption - |-------------------------------------------------------------------------- - | - | By default Laravel encrypt cookies for security reason. - | If you decide to not decrypt cookies, you will have to configure Laravel - | to not encrypt your cookie token by adding its name into the $except - | array available in the middleware "EncryptCookies" provided by Laravel. - | see https://laravel.com/docs/master/responses#cookies-and-encryption - | for details. - | - | Set it to true if you want to decrypt cookies. - | - */ - - 'decrypt_cookies' => false, - - /* - |-------------------------------------------------------------------------- - | Providers - |-------------------------------------------------------------------------- - | - | Specify the various providers used throughout the package. - | - */ - - 'providers' => [ - - /* - |-------------------------------------------------------------------------- - | JWT Provider - |-------------------------------------------------------------------------- - | - | Specify the provider that is used to create and decode the tokens. - | - */ - - 'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class, - - /* - |-------------------------------------------------------------------------- - | Authentication Provider - |-------------------------------------------------------------------------- - | - | Specify the provider that is used to authenticate users. - | - */ - - 'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class, - - /* - |-------------------------------------------------------------------------- - | Storage Provider - |-------------------------------------------------------------------------- - | - | Specify the provider that is used to store tokens in the blacklist. - | - */ - - 'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class, - - ], - -]; diff --git a/modules/User/Events/Login.php b/modules/User/Events/Login.php index 8866f35..9f46172 100644 --- a/modules/User/Events/Login.php +++ b/modules/User/Events/Login.php @@ -6,6 +6,7 @@ use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Http\Request; use Illuminate\Queue\SerializesModels; +use Modules\User\Models\User; class Login { @@ -18,7 +19,7 @@ class Login */ public function __construct( public Request $request, - public string $token + public User $user ) { } } diff --git a/modules/User/Http/Controllers/AuthController.php b/modules/User/Http/Controllers/AuthController.php index 95a61a7..635039e 100644 --- a/modules/User/Http/Controllers/AuthController.php +++ b/modules/User/Http/Controllers/AuthController.php @@ -4,10 +4,12 @@ namespace Modules\User\Http\Controllers; use Catch\Base\CatchController as Controller; use Catch\Exceptions\FailedException; +use Illuminate\Auth\RequestGuard; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Event; use Modules\User\Events\Login; +use Modules\User\Models\User; class AuthController extends Controller { @@ -15,11 +17,14 @@ class AuthController extends Controller * @param Request $request * @return array */ - public function login(Request $request) + public function login(Request $request): array { - $token = Auth::guard(getGuardName())->attempt($request->only(['email', 'password'])); + /* @var User $user */ + $user = User::query()->where('email', $request->get('email'))->first(); - Event::dispatch(new Login($request, $token)); + $token = $user?->createToken('token')->plainTextToken; + + Event::dispatch(new Login($request, $user)); if (! $token) { throw new FailedException('登录失败!请检查邮箱或者密码'); @@ -34,10 +39,11 @@ class AuthController extends Controller * * @return bool */ - public function logout() + public function logout(): bool { - // Auth::guard(Helper::getGuardName())->logout(); + /* @var User $user */ + $user = Auth::guard(getGuardName())->user(); - return true; + return $user->currentAccessToken()->delete(); } } diff --git a/modules/User/Listeners/Login.php b/modules/User/Listeners/Login.php index 481f30f..19d72b3 100644 --- a/modules/User/Listeners/Login.php +++ b/modules/User/Listeners/Login.php @@ -23,20 +23,16 @@ class Login { $request = $event->request; - $this->log($request, (bool) $event->token); + $this->log($request, (bool) $event->user); - if ($event->token) { - /* @var User $user */ - $user = Auth::guard(getGuardName())->user(); - - $user->login_ip = $request->ip(); - $user->login_at = time(); - $user->remember_token = $event->token; - $user->save(); + if ($event->user) { + $event->user->login_ip = $request->ip(); + $event->user->login_at = time(); + $event->user->remember_token = null; + $event->user->save(); } } - - + /** * login log * diff --git a/modules/User/Models/LogOperate.php b/modules/User/Models/LogOperate.php index 743f944..c37a59e 100644 --- a/modules/User/Models/LogOperate.php +++ b/modules/User/Models/LogOperate.php @@ -52,7 +52,6 @@ class LogOperate extends Model [$module, $controller, $action] = CatchAdmin::parseFromRouteAction(); $requestStartAt = app(Kernel::class)->requestStartedAt()->getPreciseTimestamp(3); - $params = $request->all(); // 如果参数过长则不记录 if (!empty($params)) { @@ -62,7 +61,6 @@ class LogOperate extends Model } $timeTaken = intval(microtime(true) * 1000 - $requestStartAt); - $this->storeBy([ 'module' => $module, 'action' => $controller . '@' . $action, diff --git a/modules/User/Models/User.php b/modules/User/Models/User.php index 990a9da..b64938b 100644 --- a/modules/User/Models/User.php +++ b/modules/User/Models/User.php @@ -5,8 +5,8 @@ namespace Modules\User\Models; use Catch\Base\CatchModel as Model; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Database\Eloquent\Casts\Attribute; +use Laravel\Sanctum\HasApiTokens; use Modules\User\Models\Traits\UserRelations; -use Tymon\JWTAuth\Contracts\JWTSubject; use Illuminate\Auth\Authenticatable; /** @@ -23,9 +23,9 @@ use Illuminate\Auth\Authenticatable; * @property int $updated_at * @property string $remember_token */ -class User extends Model implements AuthenticatableContract, JWTSubject +class User extends Model implements AuthenticatableContract { - use Authenticatable, UserRelations; + use Authenticatable, UserRelations, HasApiTokens; protected $fillable = [ 'id', 'username', 'email', 'avatar', 'password', 'remember_token', 'creator_id', 'status', 'department_id', 'login_ip', 'login_at', 'created_at', 'updated_at', 'deleted_at' @@ -57,25 +57,6 @@ class User extends Model implements AuthenticatableContract, JWTSubject */ protected array $formRelations = ['roles', 'jobs']; - /** - * - * @return mixed - */ - public function getJWTIdentifier(): mixed - { - return $this->getKey(); - } - - /** - * Return a key value array, containing any custom claims to be added to the JWT. - * - * @return array - */ - public function getJWTCustomClaims(): array - { - return []; - } - /** * password * diff --git a/modules/User/database/seeder/User.php b/modules/User/database/seeder/User.php index 73a564b..04f2532 100644 --- a/modules/User/database/seeder/User.php +++ b/modules/User/database/seeder/User.php @@ -1,6 +1,5 @@