From c1d6c48f5b8c01aabdc4feaa9b47c4c929d3d7c0 Mon Sep 17 00:00:00 2001 From: Edward Yang Date: Mon, 10 Apr 2023 14:54:50 +0800 Subject: [PATCH] Add jwt and admin token to build API. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add jwt to build API. 返回当前客户 后台添加,通过token获取后台用户信息 fixed token api fixed order list and order detail fixed product api fixed categoryies API add brands fixed brands add products 添加订单接口 --- app/Http/Kernel.php | 7 + app/Http/Middleware/AdminApiAuthenticate.php | 99 +++++ .../API/Controllers/Admin/BrandController.php | 100 +++++ .../Controllers/Admin/CategoryController.php | 112 ++++++ .../API/Controllers/Admin/OrderController.php | 95 +++++ .../Controllers/Admin/ProductController.php | 125 +++++++ .../API/Controllers/Admin/UserController.php | 20 + beike/API/Controllers/AuthController.php | 94 +++++ beike/API/Providers/APIServiceProvider.php | 38 ++ beike/API/Routes/api.php | 52 +++ .../Http/Controllers/AccountController.php | 4 +- .../Admin/Providers/AdminServiceProvider.php | 3 +- beike/Helpers.php | 27 +- beike/Libraries/Registry.php | 84 +++++ beike/Models/AdminUser.php | 23 +- beike/Models/AdminUserToken.php | 2 - beike/Models/Customer.php | 23 +- beike/Repositories/AdminUserTokenRepo.php | 30 +- composer.json | 3 +- composer.lock | 348 +++++++++++++++++- config/app.php | 1 + config/jwt.php | 301 +++++++++++++++ resources/lang/en/admin/account.php | 2 +- resources/lang/zh_cn/admin/account.php | 2 +- 24 files changed, 1577 insertions(+), 18 deletions(-) create mode 100644 app/Http/Middleware/AdminApiAuthenticate.php create mode 100644 beike/API/Controllers/Admin/BrandController.php create mode 100644 beike/API/Controllers/Admin/CategoryController.php create mode 100644 beike/API/Controllers/Admin/OrderController.php create mode 100644 beike/API/Controllers/Admin/ProductController.php create mode 100644 beike/API/Controllers/Admin/UserController.php create mode 100644 beike/API/Controllers/AuthController.php create mode 100644 beike/API/Providers/APIServiceProvider.php create mode 100644 beike/API/Routes/api.php create mode 100644 beike/Libraries/Registry.php create mode 100644 config/jwt.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index d5b08299..726eeada 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -64,11 +64,18 @@ class Kernel extends HttpKernel \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], + 'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], + + 'admin_api' => [ + \App\Http\Middleware\AdminApiAuthenticate::class, + 'throttle:api', + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], ]; /** diff --git a/app/Http/Middleware/AdminApiAuthenticate.php b/app/Http/Middleware/AdminApiAuthenticate.php new file mode 100644 index 00000000..7586835c --- /dev/null +++ b/app/Http/Middleware/AdminApiAuthenticate.php @@ -0,0 +1,99 @@ + + * @created 2023-04-20 14:44:54 + * @modified 2023-04-20 14:44:54 + */ + +namespace App\Http\Middleware; + +use Beike\Repositories\AdminUserTokenRepo; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Route; +use Illuminate\Validation\UnauthorizedException; + +class AdminApiAuthenticate +{ + public const ADMIN_API_PREFIX = 'admin_api.'; + + /** + * Handle an incoming request. + * + * @param Request $request + * @param \Closure $next + * @return mixed + */ + public function handle(Request $request, \Closure $next) + { + $token = $request->header('token'); + if (empty($token)) { + $token = $request->get('token'); + } + + $token = AdminUserTokenRepo::getAdminUserTokenByToken($token); + if (empty($token)) { + throw new UnauthorizedException(trans('customer.unauthorized_without_token')); + } + + $adminUser = $token->adminUser; + if (! $this->hasPermission($adminUser)) { + throw new UnauthorizedException(trans('customer.unauthorized_without_permission')); + } + + register('admin_user', $adminUser); + + return $next($request); + } + + private function hasPermission($adminUser) + { + // $routeUri = Route::current()->uri(); + $routeName = Route::currentRouteName(); + + $routePath = str_replace(self::ADMIN_API_PREFIX, '', $routeName); + if ($routePath == 'me') { + return true; + } + + $permissionName = $this->mapPermissionByRoute($routePath); + if (empty($permissionName)) { + return false; + } + + return $adminUser->can($permissionName); + } + + private function mapPermissionByRoute($routePath) + { + $maps = [ + 'categories.index' => 'categories_index', + 'categories.show' => 'categories_show', + 'categories.create' => 'categories_create', + 'categories.update' => 'categories_update', + 'categories.delete' => 'categories_delete', + + 'brands.index' => 'brands_index', + 'brands.show' => 'brands_show', + 'brands.create' => 'brands_create', + 'brands.update' => 'brands_update', + 'brands.delete' => 'brands_delete', + + 'orders.index' => 'orders_index', + 'orders.show' => 'orders_show', + 'orders.update_status' => 'orders_update_status', + 'orders.update_shipment' => 'orders_update_status', + + 'products.index' => 'products_index', + 'products.show' => 'products_show', + 'products.create' => 'products_create', + 'products.update' => 'products_update', + 'products.delete' => 'products_delete', + ]; + + return $maps[$routePath] ?? ''; + } +} diff --git a/beike/API/Controllers/Admin/BrandController.php b/beike/API/Controllers/Admin/BrandController.php new file mode 100644 index 00000000..490c24f2 --- /dev/null +++ b/beike/API/Controllers/Admin/BrandController.php @@ -0,0 +1,100 @@ + + * @created 2023-04-20 17:19:51 + * @modified 2023-04-20 17:19:51 + */ + +namespace Beike\API\Controllers\Admin; + +use Beike\Models\Brand; +use Beike\Repositories\BrandRepo; +use Illuminate\Http\Request; + +class BrandController +{ + /** + * 显示品牌列表 + * @param Request $request + * @return mixed + */ + public function index(Request $request) + { + $brands = BrandRepo::list($request->only('name', 'first', 'status')); + $data = [ + 'brands' => $brands, + ]; + + return hook_filter('admin_api.brand.index.data', $data); + } + + /** + * 创建品牌 + * + * @param Request $request + * @param Brand $brand + * @return Brand + */ + public function show(Request $request, Brand $brand): Brand + { + return hook_filter('admin_api.brand.show.data', $brand); + } + + /** + * 创建品牌 + * + * @param Request $request + * @return array + */ + public function store(Request $request): array + { + $requestData = $request->all(); + $data = [ + 'request_data' => $requestData, + ]; + + hook_action('admin_api.brand.store.before', $data); + $brand = BrandRepo::create($requestData); + hook_action('admin_api.brand.store.after', ['brand' => $brand, 'request_data' => $requestData]); + + return json_success(trans('common.created_success'), $brand); + } + + /** + * @param Request $request + * @param Brand $brand + * @return array + * @throws \Exception + */ + public function update(Request $request, Brand $brand): array + { + $requestData = $request->all(); + $data = [ + 'brand_id' => $brand, + 'request_data' => $requestData, + ]; + hook_action('admin_api.brand.update.before', $data); + $brand = BrandRepo::update($brand, $requestData); + hook_action('admin_api.brand.update.after', $data); + + return json_success(trans('common.updated_success'), $brand); + } + + /** + * @param Request $request + * @param Brand $brand + * @return array + */ + public function destroy(Request $request, Brand $brand): array + { + hook_action('admin_api.brand.destroy.before', $brand); + BrandRepo::delete($brand); + hook_action('admin_api.brand.destroy.after', $brand); + + return json_success(trans('common.deleted_success')); + } +} diff --git a/beike/API/Controllers/Admin/CategoryController.php b/beike/API/Controllers/Admin/CategoryController.php new file mode 100644 index 00000000..37bac64f --- /dev/null +++ b/beike/API/Controllers/Admin/CategoryController.php @@ -0,0 +1,112 @@ + + * @created 2023-04-20 17:00:40 + * @modified 2023-04-20 17:00:40 + */ + +namespace Beike\API\Controllers\Admin; + +use Beike\Admin\Http\Requests\CategoryRequest; +use Beike\Admin\Http\Resources\CategoryResource; +use Beike\Admin\Services\CategoryService; +use Beike\Models\Category; +use Beike\Repositories\CategoryRepo; +use Illuminate\Http\Request; + +class CategoryController +{ + /** + * 商品分类列表 + * + * @return mixed + */ + public function index() + { + $categories = CategoryRepo::getAdminList(); + $data = [ + 'categories' => CategoryResource::collection($categories), + ]; + + return hook_filter('admin_api.category.index.data', $data); + } + + /** + * 单个商品分类 + * + * @param Request $request + * @param Category $category + * @return mixed + */ + public function show(Request $request, Category $category) + { + if (! $category->active) { + return []; + } + $category->load('description'); + + return hook_filter('admin_api.category.show.data', $category); + } + + /** + * 保存商品分类 + * + * @param CategoryRequest $request + * @return array + * @throws \Exception + */ + public function store(CategoryRequest $request) + { + $requestData = $request->all(); + $category = (new CategoryService())->createOrUpdate($requestData, null); + $data = [ + 'category' => $category, + 'request_data' => $requestData, + ]; + + hook_action('admin_api.category.save.after', $data); + + return $data; + } + + /** + * 更新产品分类 + * + * @param CategoryRequest $request + * @param Category $category + * @return array + * @throws \Exception + */ + public function update(CategoryRequest $request, Category $category) + { + $requestData = $request->all(); + $category = (new CategoryService())->createOrUpdate($requestData, $category); + $data = [ + 'category' => $category, + 'request_data' => $requestData, + ]; + + hook_action('admin_api.category.save.after', $data); + + return $data; + } + + /** + * 删除分类 + * @param Request $request + * @param Category $category + * @return array + * @throws \Exception + */ + public function destroy(Request $request, Category $category): array + { + CategoryRepo::delete($category); + hook_action('admin.category.destroy.after', $category); + + return json_success(trans('common.deleted_success')); + } +} diff --git a/beike/API/Controllers/Admin/OrderController.php b/beike/API/Controllers/Admin/OrderController.php new file mode 100644 index 00000000..19a84fbb --- /dev/null +++ b/beike/API/Controllers/Admin/OrderController.php @@ -0,0 +1,95 @@ + + * @created 2023-04-20 16:40:35 + * @modified 2023-04-20 16:40:35 + */ + +namespace Beike\API\Controllers\Admin; + +use Beike\Models\Order; +use Beike\Models\OrderShipment; +use Beike\Repositories\OrderRepo; +use Beike\Services\ShipmentService; +use Beike\Services\StateMachineService; +use Illuminate\Http\Request; + +class OrderController +{ + /** + * 获取订单列表 + * + * @param Request $request + * @return mixed + * @throws \Exception + */ + public function index(Request $request) + { + $orders = OrderRepo::filterOrders($request->all()); + + return hook_filter('admin_api.order.index.data', $orders); + } + + /** + * 查看单个订单 + * + * @param Request $request + * @param Order $order + * @return mixed + * @throws \Exception + */ + public function show(Request $request, Order $order) + { + $order->load(['orderTotals', 'orderHistories', 'orderShipments']); + $data = hook_filter('admin.order.show.data', ['order' => $order, 'html_items' => []]); + $data['statuses'] = StateMachineService::getInstance($order)->nextBackendStatuses(); + + return hook_filter('admin_api.order.show.data', $data); + } + + /** + * 更新订单状态,添加订单更新日志 + * + * @param Request $request + * @param Order $order + * @return array + * @throws \Throwable + */ + public function updateStatus(Request $request, Order $order) + { + $status = $request->get('status'); + $comment = $request->get('comment'); + $notify = $request->get('notify'); + + $shipment = ShipmentService::handleShipment(\request('express_code'), \request('express_number')); + + $stateMachine = new StateMachineService($order); + $stateMachine->setShipment($shipment)->changeStatus($status, $comment, $notify); + + $orderStatusData = $request->all(); + + hook_action('admin.order.update_status.after', $orderStatusData); + + return json_success(trans('common.updated_success')); + } + + /** + * 更新发货信息 + */ + public function updateShipment(Request $request, Order $order, int $orderShipmentId): array + { + $data = $request->all(); + $orderShipment = OrderShipment::query()->where('order_id', $order->id)->findOrFail($orderShipmentId); + ShipmentService::updateShipment($orderShipment, $data); + hook_action('admin.order.update_shipment.after', [ + 'request_data' => $data, + 'shipment' => $orderShipment, + ]); + + return json_success(trans('common.updated_success')); + } +} diff --git a/beike/API/Controllers/Admin/ProductController.php b/beike/API/Controllers/Admin/ProductController.php new file mode 100644 index 00000000..ec9fe594 --- /dev/null +++ b/beike/API/Controllers/Admin/ProductController.php @@ -0,0 +1,125 @@ + + * @created 2023-04-20 16:48:47 + * @modified 2023-04-20 16:48:47 + */ + +namespace Beike\API\Controllers\Admin; + +use Beike\Admin\Http\Requests\ProductRequest; +use Beike\Admin\Http\Resources\ProductResource; +use Beike\Admin\Services\ProductService; +use Beike\Models\Product; +use Beike\Repositories\ProductRepo; +use Beike\Shop\Http\Resources\ProductDetail; +use Illuminate\Http\Request; + +class ProductController +{ + /** + * 产品列表 + * + * @param Request $request + * @return mixed + */ + public function index(Request $request) + { + $requestData = $request->all(); + if (! isset($requestData['sort'])) { + $requestData['sort'] = 'products.updated_at'; + } + $productList = ProductRepo::list($requestData); + $products = ProductResource::collection($productList); + + return hook_filter('admin_api.product.index.data', $products); + } + + /** + * 产品列表 + * + * @param Request $request + * @param Product $product + * @return mixed + */ + public function show(Request $request, Product $product) + { + $relationIds = $product->relations->pluck('id')->toArray(); + $product = ProductRepo::getProductDetail($product); + + $data = [ + 'product' => (new ProductDetail($product))->jsonSerialize(), + 'relations' => ProductRepo::getProductsByIds($relationIds)->jsonSerialize(), + ]; + + return hook_filter('admin_api.product.show.data', $data); + } + + /** + * 创建商品 + * + * @param ProductRequest $request + * @return array + */ + public function store(ProductRequest $request) + { + try { + $requestData = $request->all(); + $product = (new ProductService)->create($requestData); + + $data = [ + 'request_data' => $requestData, + 'product' => $product, + ]; + hook_action('admin_api.product.store.after', $data); + + return json_success(trans('common.created_success')); + } catch (\Exception $e) { + return json_fail($e->getMessage()); + } + } + + /** + * 编辑商品 + * + * @param ProductRequest $request + * @param Product $product + * @return array + */ + public function update(ProductRequest $request, Product $product) + { + try { + $requestData = $request->all(); + $product = (new ProductService)->update($product, $requestData); + + $data = [ + 'request_data' => $requestData, + 'product' => $product, + ]; + hook_action('admin_api.product.update.after', $data); + + return json_success(trans('common.updated_success')); + } catch (\Exception $e) { + return json_fail($e->getMessage()); + } + } + + /** + * 删除商品 + * + * @param Request $request + * @param Product $product + * @return array + */ + public function destroy(Request $request, Product $product) + { + $product->delete(); + hook_action('admin_api.product.destroy.after', $product); + + return json_success(trans('common.deleted_success')); + } +} diff --git a/beike/API/Controllers/Admin/UserController.php b/beike/API/Controllers/Admin/UserController.php new file mode 100644 index 00000000..18ade398 --- /dev/null +++ b/beike/API/Controllers/Admin/UserController.php @@ -0,0 +1,20 @@ + + * @created 2023-04-20 14:51:26 + * @modified 2023-04-20 14:51:26 + */ + +namespace Beike\API\Controllers\Admin; + +class UserController +{ + public function me() + { + return registry('admin_user'); + } +} diff --git a/beike/API/Controllers/AuthController.php b/beike/API/Controllers/AuthController.php new file mode 100644 index 00000000..413a8f2b --- /dev/null +++ b/beike/API/Controllers/AuthController.php @@ -0,0 +1,94 @@ + + * @created 2023-04-11 17:44:26 + * @modified 2023-04-11 17:44:26 + */ + +namespace Beike\API\Controllers; + +use App\Http\Controllers\Controller; +use Beike\Shop\Http\Resources\CustomerResource; + +class AuthController extends Controller +{ + /** + * Create a new AuthController instance. + * + * @return void + */ + public function __construct() + { + // $this->middleware('auth:api', ['except' => ['login']]); + } + + /** + * Get a JWT via given credentials. + * + * @return \Illuminate\Http\JsonResponse + */ + public function login() + { + $credentials = request(['email', 'password']); + + if (! $token = auth('api_customer')->attempt($credentials)) { + return response()->json(['error' => 'Unauthorized'], 401); + } + + return $this->respondWithToken($token); + } + + /** + * Get the authenticated User. + * + * @return \Illuminate\Http\JsonResponse + */ + public function me() + { + $customer = auth('api_customer')->user(); + + return response()->json(new CustomerResource($customer)); + } + + /** + * Log the user out (Invalidate the token). + * + * @return \Illuminate\Http\JsonResponse + */ + public function logout() + { + auth('api_customer')->logout(); + + return response()->json(['message' => 'Successfully logged out']); + } + + /** + * Refresh a token. + * + * @return \Illuminate\Http\JsonResponse + */ + public function refresh() + { + return $this->respondWithToken(auth('api_customer')->refresh()); + } + + /** + * Get the token array structure. + * + * @param string $token + * + * @return \Illuminate\Http\JsonResponse + */ + protected function respondWithToken($token) + { + return response()->json([ + 'access_token' => $token, + 'token_type' => 'bearer', + 'expires_in' => auth('api_customer')->factory()->getTTL() * 60, + ]); + } +} diff --git a/beike/API/Providers/APIServiceProvider.php b/beike/API/Providers/APIServiceProvider.php new file mode 100644 index 00000000..a379d4f3 --- /dev/null +++ b/beike/API/Providers/APIServiceProvider.php @@ -0,0 +1,38 @@ + + * @created 2023-04-11 16:08:04 + * @modified 2023-04-11 16:08:04 + */ + +namespace Beike\API\Providers; + +use Illuminate\Support\Facades\Config; +use Illuminate\Support\ServiceProvider; + +class APIServiceProvider extends ServiceProvider +{ + public function boot() + { + if (is_installer()) { + return; + } + $this->loadRoutesFrom(__DIR__ . '/../Routes/api.php'); + $this->registerGuard(); + } + + /** + * 注册后台用户 guard + */ + protected function registerGuard() + { + Config::set('auth.guards.api_customer', [ + 'driver' => 'jwt', + 'provider' => 'shop_customer', + ]); + } +} diff --git a/beike/API/Routes/api.php b/beike/API/Routes/api.php new file mode 100644 index 00000000..a0c133b7 --- /dev/null +++ b/beike/API/Routes/api.php @@ -0,0 +1,52 @@ + + * @created 2023-04-11 17:36:05 + * @modified 2023-04-11 17:36:05 + */ + +use Illuminate\Support\Facades\Route; + +Route::prefix('api') + ->middleware(['api']) + ->name('api.') + ->group(function () { + Route::post('login', [\Beike\API\Controllers\AuthController::class, 'login']); + Route::post('logout', [\Beike\API\Controllers\AuthController::class, 'logout']); + Route::post('refresh', [\Beike\API\Controllers\AuthController::class, 'refresh']); + Route::get('me', [\Beike\API\Controllers\AuthController::class, 'me']); + }); + +Route::prefix('admin_api') + ->middleware(['admin_api']) + ->name('admin_api.') + ->group(function () { + Route::get('brands', [\Beike\API\Controllers\Admin\BrandController::class, 'index'])->name('brands.index'); + Route::get('brands/{brand}', [\Beike\API\Controllers\Admin\BrandController::class, 'show'])->name('brands.show'); + Route::post('brands', [\Beike\API\Controllers\Admin\BrandController::class, 'store'])->name('brands.create'); + Route::put('brands/{brand}', [\Beike\API\Controllers\Admin\BrandController::class, 'update'])->name('brands.update'); + Route::delete('brands/{brand}', [\Beike\API\Controllers\Admin\BrandController::class, 'destroy'])->name('brands.delete'); + + Route::get('categories', [\Beike\API\Controllers\Admin\CategoryController::class, 'index'])->name('categories.index'); + Route::get('categories/{category}', [\Beike\API\Controllers\Admin\CategoryController::class, 'show'])->name('categories.show'); + Route::post('categories', [\Beike\API\Controllers\Admin\CategoryController::class, 'store'])->name('categories.create'); + Route::put('categories/{category}', [\Beike\API\Controllers\Admin\CategoryController::class, 'update'])->name('categories.update'); + Route::delete('categories/{category}', [\Beike\API\Controllers\Admin\CategoryController::class, 'destroy'])->name('categories.delete'); + + Route::get('me', [\Beike\API\Controllers\Admin\UserController::class, 'me'])->name('me'); + + Route::get('orders', [\Beike\API\Controllers\Admin\OrderController::class, 'index'])->name('orders.index'); + Route::get('orders/{order}', [\Beike\API\Controllers\Admin\OrderController::class, 'show'])->name('orders.show'); + Route::put('orders/{order}/status', [\Beike\API\Controllers\Admin\OrderController::class, 'updateStatus'])->name('orders.update_status'); + Route::put('orders/{order}/shipments/{shipment}', [\Beike\API\Controllers\Admin\OrderController::class, 'updateShipment'])->name('orders.update_shipment'); + + Route::get('products', [\Beike\API\Controllers\Admin\ProductController::class, 'index'])->name('products.index'); + Route::get('products/{product}', [\Beike\API\Controllers\Admin\ProductController::class, 'show'])->name('products.show'); + Route::post('products', [\Beike\API\Controllers\Admin\ProductController::class, 'store'])->name('products.create'); + Route::put('products/{product}', [\Beike\API\Controllers\Admin\ProductController::class, 'update'])->name('products.update'); + Route::delete('products/{product}', [\Beike\API\Controllers\Admin\ProductController::class, 'destroy'])->name('products.delete'); + }); diff --git a/beike/Admin/Http/Controllers/AccountController.php b/beike/Admin/Http/Controllers/AccountController.php index 7f1e39a2..1fe4863b 100644 --- a/beike/Admin/Http/Controllers/AccountController.php +++ b/beike/Admin/Http/Controllers/AccountController.php @@ -22,19 +22,19 @@ class AccountController extends Controller $user = current_user(); $data = [ 'current_user' => $user, - 'tokens' => AdminUserTokenRepo::getTokenByAdminUser($user)->pluck('token')->toArray() + 'tokens' => AdminUserTokenRepo::getTokenByAdminUser($user)->pluck('token')->toArray(), ]; return view('admin::pages.account.index', $data); } - public function update(Request $request) { $user = current_user(); $adminUserData = $request->all(); AdminUserRepo::updateAdminUser($user->id, $adminUserData); + return response()->redirectTo('admin/account')->with('success', trans('common.updated_success')); } } diff --git a/beike/Admin/Providers/AdminServiceProvider.php b/beike/Admin/Providers/AdminServiceProvider.php index 7c8f1610..c09e2b97 100644 --- a/beike/Admin/Providers/AdminServiceProvider.php +++ b/beike/Admin/Providers/AdminServiceProvider.php @@ -53,6 +53,7 @@ class AdminServiceProvider extends ServiceProvider load_settings(); $this->loadRoutesFrom(__DIR__ . '/../Routes/admin.php'); + $this->registerGuard(); $adminName = admin_name(); if (! Str::startsWith($uri, "/{$adminName}")) { @@ -69,8 +70,6 @@ class AdminServiceProvider extends ServiceProvider $this->loadAdminViewComponents(); - $this->registerGuard(); - Config::set('filesystems.disks.catalog', [ 'driver' => 'local', 'root' => public_path('catalog'), diff --git a/beike/Helpers.php b/beike/Helpers.php index 6fdb9a4d..90b6e74d 100644 --- a/beike/Helpers.php +++ b/beike/Helpers.php @@ -209,7 +209,12 @@ function equal_route($routeName): bool */ function current_user(): ?AdminUser { - return auth()->guard(AdminUser::AUTH_GUARD)->user(); + $user = auth()->guard(AdminUser::AUTH_GUARD)->user(); + if (empty($user)) { + $user = registry('admin_user'); + } + + return $user; } /** @@ -718,3 +723,23 @@ function perPage(): int { return (int) system_setting('base.product_per_page', 20); } + +/** + * @param $key + * @param $value + * @param bool $force + */ +function register($key, $value, bool $force = false) +{ + \Beike\Libraries\Registry::set($key, $value, $force); +} + +/** + * @param $key + * @param null $default + * @return mixed + */ +function registry($key, $default = null): mixed +{ + return \Beike\Libraries\Registry::get($key, $default); +} diff --git a/beike/Libraries/Registry.php b/beike/Libraries/Registry.php new file mode 100644 index 00000000..4d62993f --- /dev/null +++ b/beike/Libraries/Registry.php @@ -0,0 +1,84 @@ + + * @created 2023-04-20 16:29:54 + * @modified 2023-04-20 16:29:54 + */ + +namespace Beike\Libraries; + +class Registry +{ + private array $data = []; + + private static $registry; + + public static function getSingleton(): self + { + if (self::$registry instanceof self) { + return self::$registry; + } + + return self::$registry = new self(); + } + + /** + * @param $key + * @param null $default + * @return mixed + */ + public static function get($key, $default = null): mixed + { + return self::getSingleton()->getValue($key, $default); + } + + /** + * @param $key + * @param $value + * @param bool $force + */ + public static function set($key, $value, bool $force = false) + { + if (self::getSingleton()->has($key) && ! $force) { + return; + } + self::getSingleton()->setValue($key, $value); + } + + public function destroy() + { + self::$registry = null; + } + + /** + * @param $key + * @param null $default + * @return mixed + */ + public function getValue($key, $default = null): mixed + { + return $this->data[$key] ?? $default; + } + + /** + * @param $key + * @param $value + */ + public function setValue($key, $value) + { + $this->data[$key] = $value; + } + + /** + * @param $key + * @return bool + */ + public function has($key): bool + { + return isset($this->data[$key]); + } +} diff --git a/beike/Models/AdminUser.php b/beike/Models/AdminUser.php index 9d3c7d80..b9698aa8 100644 --- a/beike/Models/AdminUser.php +++ b/beike/Models/AdminUser.php @@ -8,8 +8,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as AuthUser; use Illuminate\Notifications\Notifiable; use Spatie\Permission\Traits\HasRoles; +use Tymon\JWTAuth\Contracts\JWTSubject; -class AdminUser extends AuthUser +class AdminUser extends AuthUser implements JWTSubject { use HasFactory, HasRoles; use Notifiable; @@ -32,4 +33,24 @@ class AdminUser extends AuthUser $this->notifyNow(new AdminForgottenNotification($this, $code)); } } + + /** + * Get the identifier that will be stored in the subject claim of the JWT. + * + * @return mixed + */ + public function getJWTIdentifier() + { + return $this->getKey(); + } + + /** + * Return a key value array, containing any custom claims to be added to the JWT. + * + * @return array + */ + public function getJWTCustomClaims() + { + return []; + } } diff --git a/beike/Models/AdminUserToken.php b/beike/Models/AdminUserToken.php index 52403005..af54b61a 100644 --- a/beike/Models/AdminUserToken.php +++ b/beike/Models/AdminUserToken.php @@ -18,10 +18,8 @@ class AdminUserToken extends Model { protected $fillable = ['admin_user_id', 'token']; - public function adminUser(): BelongsTo { return $this->belongsTo(AdminUser::class); } - } diff --git a/beike/Models/Customer.php b/beike/Models/Customer.php index dea03edc..1fe77dd3 100644 --- a/beike/Models/Customer.php +++ b/beike/Models/Customer.php @@ -11,8 +11,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; +use Tymon\JWTAuth\Contracts\JWTSubject; -class Customer extends Authenticatable +class Customer extends Authenticatable implements JWTSubject { use HasFactory; use SoftDeletes; @@ -66,4 +67,24 @@ class Customer extends Authenticatable $this->notifyNow(new ForgottenNotification($this, $code)); } } + + /** + * Get the identifier that will be stored in the subject claim of the JWT. + * + * @return mixed + */ + public function getJWTIdentifier() + { + return $this->getKey(); + } + + /** + * Return a key value array, containing any custom claims to be added to the JWT. + * + * @return array + */ + public function getJWTCustomClaims() + { + return []; + } } diff --git a/beike/Repositories/AdminUserTokenRepo.php b/beike/Repositories/AdminUserTokenRepo.php index afc75c5d..2875afae 100644 --- a/beike/Repositories/AdminUserTokenRepo.php +++ b/beike/Repositories/AdminUserTokenRepo.php @@ -16,37 +16,58 @@ use Beike\Models\AdminUserToken; class AdminUserTokenRepo { + /** + * @param $adminUser + * @return mixed + */ public static function getTokenByAdminUser($adminUser) { $adminUserId = self::getAdminUserId($adminUser); if (empty($adminUserId)) { return null; } + return AdminUserToken::query()->where('admin_user_id', $adminUserId)->get(); } + /** + * @param $token + * @return mixed + */ + public static function getAdminUserTokenByToken($token) + { + return AdminUserToken::query()->where('token', $token)->first(); + } + /** + * @param $adminUser + * @param $tokens + * @return void + */ public static function updateTokensByUser($adminUser, $tokens) { $adminUserId = self::getAdminUserId($adminUser); if (empty($adminUserId)) { - return null; + return; } AdminUserToken::query()->where('admin_user_id', $adminUserId)->delete(); if (empty($tokens)) { - return null; + return; } foreach ($tokens as $token) { AdminUserToken::query()->create([ 'admin_user_id' => $adminUserId, - 'token' => $token + 'token' => $token, ]); } } - + /** + * @param $adminUser + * @return int|mixed + */ private static function getAdminUserId($adminUser) { $adminUserId = 0; @@ -55,6 +76,7 @@ class AdminUserTokenRepo } elseif (is_int($adminUser)) { $adminUserId = $adminUser; } + return $adminUserId; } } diff --git a/composer.json b/composer.json index 81bb7853..ebaba001 100644 --- a/composer.json +++ b/composer.json @@ -7,8 +7,8 @@ "require": { "php": "^8.0.2", "ext-curl": "*", - "ext-iconv": "*", "ext-fileinfo": "*", + "ext-iconv": "*", "ext-json": "*", "ext-pdo": "*", "ext-simplexml": "*", @@ -26,6 +26,7 @@ "srmklive/paypal": "^3.0", "stripe/stripe-php": "^8.8", "tormjens/eventy": "^0.8.0", + "tymon/jwt-auth": "^2.0", "ultrono/laravel-sitemap": "^9.1", "unisharp/doc-us": "^1.3", "zanysoft/laravel-zip": "^2.0" diff --git a/composer.lock b/composer.lock index 6c54cd4c..d5c64255 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "36d52cf08b3c0a6bcfc69644de7ff3aa", + "content-hash": "db85c224767389a98090ed325dbdd7ce", "packages": [ { "name": "brick/math", @@ -2124,6 +2124,153 @@ }, "time": "2023-02-15T16:40:09+00:00" }, + { + "name": "lcobucci/clock", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/clock.git", + "reference": "fb533e093fd61321bfcbac08b131ce805fe183d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/fb533e093fd61321bfcbac08b131ce805fe183d3", + "reference": "fb533e093fd61321bfcbac08b131ce805fe183d3", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^8.0", + "stella-maris/clock": "^0.1.4" + }, + "require-dev": { + "infection/infection": "^0.26", + "lcobucci/coding-standard": "^8.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com" + } + ], + "description": "Yet another clock abstraction", + "support": { + "issues": "https://github.com/lcobucci/clock/issues", + "source": "https://github.com/lcobucci/clock/tree/2.2.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2022-04-19T19:34:17+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/4d7de2fe0d51a96418c0d04004986e410e87f6b4", + "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-sodium": "*", + "lcobucci/clock": "^2.0 || ^3.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "infection/infection": "^0.21", + "lcobucci/coding-standard": "^6.0", + "mikey179/vfsstream": "^1.6.7", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/php-invoker": "^3.1", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "support": { + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/4.3.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2023-01-02T13:28:00+00:00" + }, { "name": "league/commonmark", "version": "2.3.8", @@ -3744,6 +3891,60 @@ }, "time": "2021-02-03T23:26:27+00:00" }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, { "name": "psr/container", "version": "2.0.2", @@ -4635,6 +4836,59 @@ }, "time": "2023-02-20T14:35:50+00:00" }, + { + "name": "stella-maris/clock", + "version": "0.1.7", + "source": { + "type": "git", + "url": "https://github.com/stella-maris-solutions/clock.git", + "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stella-maris-solutions/clock/zipball/fa23ce16019289a18bb3446fdecd45befcdd94f8", + "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.0|^8.0", + "psr/clock": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "StellaMaris\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Heigl", + "role": "Maintainer" + } + ], + "description": "A pre-release of the proposed PSR-20 Clock-Interface", + "homepage": "https://gitlab.com/stella-maris/clock", + "keywords": [ + "clock", + "datetime", + "point in time", + "psr20" + ], + "support": { + "source": "https://github.com/stella-maris-solutions/clock/tree/0.1.7" + }, + "time": "2022-11-25T16:15:06+00:00" + }, { "name": "stripe/stripe-php", "version": "v8.12.0", @@ -7253,6 +7507,96 @@ }, "time": "2021-10-22T08:33:10+00:00" }, + { + "name": "tymon/jwt-auth", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/tymondesigns/jwt-auth.git", + "reference": "b0868a5b00801889a9e0c81a737963d8004e708c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tymondesigns/jwt-auth/zipball/b0868a5b00801889a9e0c81a737963d8004e708c", + "reference": "b0868a5b00801889a9e0c81a737963d8004e708c", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "illuminate/auth": "^9.0|^10.0", + "illuminate/contracts": "^9.0|^10.0", + "illuminate/http": "^9.0|^10.0", + "illuminate/support": "^9.0|^10.0", + "lcobucci/jwt": "^4.0", + "nesbot/carbon": "^2.0", + "php": "^8.0" + }, + "require-dev": { + "illuminate/console": "^9.0|^10.0", + "illuminate/database": "^9.0|^10.0", + "illuminate/routing": "^9.0|^10.0", + "mockery/mockery": ">=0.9.9", + "phpunit/phpunit": "^9.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "1.0-dev", + "dev-2.x": "2.0-dev" + }, + "laravel": { + "aliases": { + "JWTAuth": "Tymon\\JWTAuth\\Facades\\JWTAuth", + "JWTFactory": "Tymon\\JWTAuth\\Facades\\JWTFactory" + }, + "providers": [ + "Tymon\\JWTAuth\\Providers\\LaravelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Tymon\\JWTAuth\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sean Tymon", + "email": "tymon148@gmail.com", + "homepage": "https://tymon.xyz", + "role": "Developer" + } + ], + "description": "JSON Web Token Authentication for Laravel and Lumen", + "homepage": "https://github.com/tymondesigns/jwt-auth", + "keywords": [ + "Authentication", + "JSON Web Token", + "auth", + "jwt", + "laravel" + ], + "support": { + "issues": "https://github.com/tymondesigns/jwt-auth/issues", + "source": "https://github.com/tymondesigns/jwt-auth" + }, + "funding": [ + { + "url": "https://www.patreon.com/seantymon", + "type": "patreon" + } + ], + "time": "2023-02-16T16:29:41+00:00" + }, { "name": "ultrono/laravel-sitemap", "version": "9.3.0", @@ -11175,8 +11519,8 @@ "platform": { "php": "^8.0.2", "ext-curl": "*", - "ext-iconv": "*", "ext-fileinfo": "*", + "ext-iconv": "*", "ext-json": "*", "ext-pdo": "*", "ext-simplexml": "*", diff --git a/config/app.php b/config/app.php index bded880f..6167bcd4 100644 --- a/config/app.php +++ b/config/app.php @@ -180,6 +180,7 @@ return [ Beike\Shop\Providers\ShopServiceProvider::class, Beike\Shop\Providers\PluginServiceProvider::class, Beike\Installer\Providers\InstallerServiceProvider::class, + Beike\API\Providers\APIServiceProvider::class, Beike\Hook\HookServiceProvider::class, ], diff --git a/config/jwt.php b/config/jwt.php new file mode 100644 index 00000000..f83234d1 --- /dev/null +++ b/config/jwt.php @@ -0,0 +1,301 @@ + + * + * 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', 60), + + /* + |-------------------------------------------------------------------------- + | 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/resources/lang/en/admin/account.php b/resources/lang/en/admin/account.php index d2f2dab4..4272d53f 100644 --- a/resources/lang/en/admin/account.php +++ b/resources/lang/en/admin/account.php @@ -10,6 +10,6 @@ */ return [ - 'create_token' => 'Create Token', + 'create_token' => 'Create Token', 'password_text' => 'If the password is left blank, it will not be modified', ]; diff --git a/resources/lang/zh_cn/admin/account.php b/resources/lang/zh_cn/admin/account.php index 51cac8ce..6c496236 100644 --- a/resources/lang/zh_cn/admin/account.php +++ b/resources/lang/zh_cn/admin/account.php @@ -10,6 +10,6 @@ */ return [ - 'create_token' => '生成 Token', + 'create_token' => '生成 Token', 'password_text' => '密码留空则不修改', ];