[api] 登录/登出

main
Jing Li 2024-04-07 12:53:45 +08:00
parent 7d45208cef
commit 60bc23c3b8
7 changed files with 147 additions and 18 deletions

View File

@ -0,0 +1,28 @@
<?php
namespace App\Exceptions;
use Throwable;
class RuntimeException extends \RuntimeException
{
/**
* HTTP 响应状态码
*/
protected $httpStatusCode = 400;
public function __construct(string $message = 'Bad request', int $code = 10000, ?Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
public function getHttpStatusCode(): int
{
return $this->httpStatusCode;
}
public function setHttpStatusCode(int $httpStatusCode): void
{
$this->httpStatusCode = $httpStatusCode;
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace App\Http\Controllers\Api\Auth;
use App\Exceptions\RuntimeException;
use App\Http\Controllers\Api\Controller;
use App\Models\AdminUser;
use App\Models\Employee;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class AccessTokenController extends Controller
{
public function store(Request $request): array
{
$validated = $request->validate(
rules: [
'username' => ['bail', 'required'],
'password' => ['bail', 'required'],
],
attributes: [
'username' => '账号',
'password' => '密码',
],
);
$adminUser = AdminUser::where('username', $validated['username'])->first();
if (! Hash::check($validated['password'], (string) $adminUser?->password)) {
throw ValidationException::withMessages([
'username' => ['账号或密码错误'],
]);
}
$employee = Employee::where('admin_user_id', $adminUser->id)->first();
if (is_null($employee)) {
throw new RuntimeException('员工未找到');
}
if ($employee->isResigned()) {
throw new RuntimeException('员工已离职');
}
$employee->tokens()->delete();
/** @var \Laravel\Sanctum\NewAccessToken */
$accessToken = $employee->createToken(
name: 'api',
expiresAt: now()->addDays(15),
);
return [
'token' => $accessToken->plainTextToken,
];
}
public function destroy(Request $request)
{
/** @var Employee */
if ($employee = $this->guard()->user()) {
$employee->tokens()->delete();
}
return response()->noContent();
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Auth;
class Controller extends BaseController
{
/**
* @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard('api');
}
}

View File

@ -6,16 +6,19 @@ use App\Admin\Filters\EmployeeFilter;
use App\Enums\EmployeeStatus; use App\Enums\EmployeeStatus;
use App\Traits\HasDateTimeFormatter; use App\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable; use EloquentFilter\Filterable;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Laravel\Sanctum\HasApiTokens;
use Slowlyo\OwlAdmin\Models\AdminUser; use Slowlyo\OwlAdmin\Models\AdminUser;
/** /**
* 员工 * 员工
*/ */
class Employee extends Model class Employee extends Model implements AuthenticatableContract
{ {
use Filterable, HasDateTimeFormatter; use Authenticatable, HasApiTokens, Filterable, HasDateTimeFormatter;
const JOB_KEY = 'job'; const JOB_KEY = 'job';
@ -76,6 +79,14 @@ class Employee extends Model
return $q->where('employee_status', EmployeeStatus::Online); return $q->where('employee_status', EmployeeStatus::Online);
} }
/**
* 确认当前员工是否已离职
*/
public function isResigned(): bool
{
return $this->employee_status === EmployeeStatus::Offline;
}
protected function employeeStatusText(): Attribute protected function employeeStatusText(): Attribute
{ {
return new Attribute( return new Attribute(

View File

@ -31,6 +31,7 @@ class AppServiceProvider extends ServiceProvider
Relation::enforceMorphMap( Relation::enforceMorphMap(
collect([ collect([
\App\Models\AdminUser::class, \App\Models\AdminUser::class,
\App\Models\Employee::class,
\App\Models\EmployeeSignRepair::class, \App\Models\EmployeeSignRepair::class,
\App\Models\HolidayApply::class, \App\Models\HolidayApply::class,
\App\Models\OvertimeApply::class, \App\Models\OvertimeApply::class,

View File

@ -38,7 +38,12 @@ return [
'guards' => [ 'guards' => [
'web' => [ 'web' => [
'driver' => 'session', 'driver' => 'session',
'provider' => 'users', 'provider' => 'admin_users',
],
'api' => [
'driver' => 'sanctum',
'provider' => 'employees',
], ],
], ],
@ -60,9 +65,14 @@ return [
*/ */
'providers' => [ 'providers' => [
'users' => [ 'admin_users' => [
'driver' => 'eloquent', 'driver' => 'eloquent',
'model' => App\Models\User::class, 'model' => App\Models\AdminUser::class,
],
'employees' => [
'driver' => 'eloquent',
'model' => App\Models\Employee::class,
], ],
// 'users' => [ // 'users' => [

View File

@ -1,19 +1,13 @@
<?php <?php
use Illuminate\Http\Request; use App\Http\Controllers\Api\Auth\AccessTokenController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
/* Route::post('/auth/login', [AccessTokenController::class, 'store']);
|-------------------------------------------------------------------------- Route::delete('/auth/logout', [AccessTokenController::class, 'destroy']);
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) { Route::group([
return $request->user(); 'middleware' => ['auth:api'],
], function () {
//
}); });