批改状态:合格
老师批语:
app/Http/Kernel.php
protected $routeMiddleware = [......'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,];
https://packagist.org/packages/liyu/dingo-serializer-switch
$api->version('v1',['middleware' => 'serializer:array'],function ($api) {});
JWT 全称叫 JSON Web Token, 是一个非常轻巧的规范。这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息。
composer require tymon/jwt-auth:1.0.x-dev
运行以下命令以发布包配置文件:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
您现在应该有一个config/jwt.php文件,允许您配置此包的基础知识。
我已经包含了一个帮助命令来为你生成一个密钥:
php artisan jwt:secret
首先,您需要Tymon\JWTAuth\Contracts\JWTSubject在 User 模型上实现合同,这需要您实现 2 个方法getJWTIdentifier()和getJWTCustomClaims().
下面的示例应该让您了解它的外观。显然,您应该根据自己的需要进行任何更改。
<?phpnamespace App;use Tymon\JWTAuth\Contracts\JWTSubject;use Illuminate\Notifications\Notifiable;use Illuminate\Foundation\Auth\User as Authenticatable;class User extends Authenticatable implements JWTSubject{use Notifiable;// Rest omitted for brevity/*** 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 [];}}
在该config/auth.php文件中,您需要进行一些更改以配置 Laravel 以使用jwt防护来支持您的应用程序身份验证。
对文件进行以下更改:
'defaults' => ['guard' => 'api','passwords' => 'users',],...'guards' => ['api' => ['driver' => 'jwt','provider' => 'users',],],
这里我们告诉api守卫使用jwt驱动程序,我们将api守卫设置为默认值。
我们现在可以使用 Laravel 内置的 Auth 系统,由 jwt-auth 在幕后完成工作!
因为我们用的dingoapi 我们还需要在 config/api.php 里面修改:
'auth' => ['jwt' => 'Dingo\Api\Auth\Provider\JWT',],
<?phpuse App\Http\Controllers\Api\UserController;use App\Http\Controllers\Auth\LoginController;use App\Http\Controllers\Auth\RegisterController;$api = app('Dingo\Api\Routing\Router');$api->version(['v1','v2'], ['middleware' => 'api.throttle', 'limit' => 100, 'expires' => 5],function ($api) {$api->group(['prefix' => 'auth'], function ($api) {// 注册$api->post('register', [RegisterController::class, 'store']);$api->post('login', [LoginController::class, 'login']);});});
创建控制器
php artisan make:controller Auth/LoginControllerphp artisan make:controller Auth/RegisterController
/*** 用户注册*/public function store(RegisterRequest $request){$user = new User();$user->name = $request->input('name');$user->email = $request->input('email');$user->password = bcrypt($request->input('password'));if ($request->input('openid')) $user->openid = $request->input('openid');if ($request->input('avatar')) $user->avatar = $request->input('avatar');$user->save();return $this->response->created();}
创建数据注册数据验证
php artisan make:request Auth/RegisterRequest
/*** Get the validation rules that apply to the request.** @return array*/public function rules(){return ['name' => 'required|max:16','email' => 'required|email|unique:users','password' => 'required|min:6|max:16|confirmed','openid' => 'sometimes|required|unique:users,openid'];}public function messages(){return ['name.required' => '昵称 不能为空','name.max' => '昵称 不能超过16个字符','openid.required' => 'openid 不能为空','openid.unique' => 'openid 已绑定其他用户',];}
LoginController
因为我们用户有禁用的功能 所以我们还需要调整一下
/*** Get a JWT via given credentials.** @return \Illuminate\Http\JsonResponse*/public function login(){$credentials = request(['email', 'password']);if (! $token = auth()->attempt($credentials)) {return response()->json(['error' => 'Unauthorized'], 401);}return $this->respondWithToken($token);}/*** Get the authenticated User.** @return \Illuminate\Http\JsonResponse*/public function me(){return response()->json(auth()->user());}/*** Log the user out (Invalidate the token).** @return \Illuminate\Http\JsonResponse*/public function logout(){auth()->logout();return response()->json(['message' => 'Successfully logged out']);}/*** Refresh a token.** @return \Illuminate\Http\JsonResponse*/public function refresh(){return $this->respondWithToken(auth()->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()->factory()->getTTL() * 60]);}
/*** 登录*/public function login(LoginRequest $request){$credentials = request(['email', 'password']);if (!$token = auth('api')->attempt($credentials)) {return $this->response->errorUnauthorized();}// 检查用户状态$user = auth('api')->user();if ($user->is_locked == 1) {return $this->response->errorForbidden('被锁定');}return $this->respondWithToken($token);}
LoginRequest
php artisan make:request Auth/LoginRequest
/*** Get the validation rules that apply to the request.** @return array*/public function rules(){return ['email' => 'required|email','password' => 'required|min:6|max:16',];}
路由
$api->group(['middleware' => 'api.auth'], function ($api) {$api->post('logout', [LoginController::class, 'logout']);});
/*** 退出登录*/public function logout(){auth('api')->logout();return $this->response->noContent();}
// 刷新token$api->post('refresh', [LoginController::class, 'refresh']);
/*** 刷新token*/public function refresh(){return $this->respondWithToken(auth('api')->refresh());}
在 app 目录下新建 helpers.php 文件, 并修改 composer.json, 加入到自动加载中:
"autoload": {"psr-4": {"App\\": "app/","Database\\Factories\\": "database/factories/","Database\\Seeders\\": "database/seeders/"},"files": ["app/helpers.php"]},
刷新自动加载:
$ composer dump-autoload
创建后台控制器
php artisan make:controller Admin/UserController --api
路由
$api->group(['prefix' => 'admin'], function ($api){// 当前登录用户详情$api->get('user', [\App\Http\Controllers\Admin\UserController::class, 'userInfo'])->name('user.info');// 禁用用户/启用用户$api->patch('users/{user}/lock', [\App\Http\Controllers\Admin\UserController::class, 'lock'])->name('users.lock');// 用户管理资源路由$api->resource('users', \App\Http\Controllers\Admin\UserController::class, ['only' => ['index', 'show', 'store', 'update']]);});
<?phpnamespace App\Http\Controllers\Admin;use App\Http\Controllers\BaseController;use App\Models\User;use App\Transformers\UserTransformer;use Illuminate\Http\Request;class UserController extends BaseController{/*** 用户个人信息详情*/public function userInfo(){return $this->response->item(auth('api')->user(), new UserTransformer());}/*** 用户列表*/public function index(Request $request){$name = $request->input('name');$email = $request->input('email');$phone = $request->input('phone');$users = User::when($name, function ($query) use ($name) {$query->where('name', 'like', "%$name%");})->when($email, function ($query) use ($email) {$query->where('email', $email);})->when($phone, function ($query) use ($phone) {$query->where('phone', $phone);})->orderBy('updated_at', 'desc')->paginate($request->query('pageSize', 10), ['*'], 'current');return $this->response->paginator($users, new UserTransformer());}/*** 添加用户*/public function store(Request $request){$request->validate(['name' => 'required|max:16','email' => 'required|email|unique:users','password' => 'required|min:6',]);User::create($request->all());return $this->response->created();}/*** 更新用户*/public function update(Request $request, User $user){$request->validate(['name' => 'required|max:16','email' => 'required|email',]);if ($user->id == 1 || $user->id == 2) return $this->response->errorBadRequest('禁止操作系统数据');$user->update($request->all());return $this->response->noContent();}/*** 用户详情*/public function show(User $user){return $this->response->item($user, new UserTransformer());}/*** 禁用和启用用户*/public function lock(User $user){if ($user->id == 1 || $user->id == 2) return $this->response->errorBadRequest('禁止操作系统数据');$user->is_locked = $user->is_locked == 0 ? 1 : 0;$user->save();return $this->response->noContent();}}
<?phpnamespace App\Transformers;use App\Models\User;use League\Fractal\TransformerAbstract;class UserTransformer extends TransformerAbstract{public function transform(User $user){return ['id' => $user->id,'name' => $user->name,'email' => $user->email,'phone' => $user->phohe,'avatar' => $user->avatar,'openid' => $user->openid,];}}
/*** 分类管理*/// 分类禁用和启用$api->patch('category/{category}/status', [\App\Http\Controllers\Admin\CategoryController::class, 'status'])->name('category.status');// 分类管理资源路由$api->resource('category', \App\Http\Controllers\Admin\CategoryController::class, ['except' => ['destroy']]);
控制器
<?phpnamespace App\Http\Controllers\Admin;use App\Http\Controllers\BaseController;use App\Models\Category;use Illuminate\Http\Request;class CategoryController extends BaseController{/*** 分类列表*/public function index(Request $request){$type = $request->input('type');if ($type == 'all') {return cache_category_all();} else {return cache_category();}}/*** 添加分类 最大2级分类*/public function store(Request $request){$insertData = $this->checkInput($request);if (!is_array($insertData)) return $insertData;Category::create($insertData);return $this->response->created();}/*** 分类详情*/public function show(Category $category){return $category;}/*** 更新分类*/public function update(Request $request, Category $category){if ($category->id < 42) return $this->response->errorBadRequest('系统数据禁止编辑, 请自行创建数据');$updateData = $this->checkInput($request);if (!is_array($updateData)) return $updateData;$category->update($updateData);return $this->response->noContent();}/*** 验证提交的参数*/protected function checkInput($request){// 验证参数$request->validate(['name' => 'required|max:16'], ['name.required' => '分类名称 不能为空']);// 获取分组$group = $request->input('group', 'goods');// 获取pid$pid = $request->input('pid', 0);// 计算level$level = $pid == 0 ? 1 : (Category::find($pid)->level + 1);// 不能超过3级分类if ($level > 2) {return $this->response->errorBadRequest('不能超过二级分类');}return ['name' => $request->input('name'),'pid' => $pid,'level' => $level,'group' => $group];}/*** 状态禁用和启用*/public function status(Category $category){if ($category->id < 42) return $this->response->errorBadRequest('系统数据禁止编辑, 请自行创建数据');$category->status = $category->status == 1 ? 0 : 1;$category->save();return $this->response->noContent();}}
Helpers.php
/*** 缓存没被禁用的分类*/if (!function_exists('cache_category')) {function cache_category (){return cache()->rememberForever('cache_category', function () {return categoryTree('goods', 1);});}}/*** 缓存所有的分类*/if (!function_exists('cache_category_all')) {function cache_category_all (){return cache()->rememberForever('cache_category_all', function () {return categoryTree('goods');});}}
/*** 清空分类缓存*/if (!function_exists('forget_cache_category')) {function forget_cache_category (){cache()->forget('cache_category');cache()->forget('cache_category_all');cache()->forget('cache_category_menu');cache()->forget('cache_category_menu_all');}}
class CategoryTransformer extends TransformerAbstract{public function transform(Category $category){return ['id' => $category->id,'pid' => $category->pid,'name' => $category->name,];}}
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号