使用 JWT 构建基本的 Api 登录接口
JWT` 安装
安装 JWT
composer require tymon/jwt-auth
发布配置
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
生成加密秘钥
php artisan jwt:secret
更新模型
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; use Tymon\JWTAuth\Contracts\JWTSubject; class User extends Authenticatable implements JWTSubject { use HasApiTokens, HasFactory, Notifiable; public function getJWTIdentifier() { return $this->getKey(); } public function getJWTCustomClaims() { return []; } }
修改
config/app.php
增加如下两条Facades当然这里可以不用注册, 直接使用助手函数
auth()
'aliases' => [ ...... 'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class, 'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class, ],
修改
config/auth.php
修改或增加guards
如果是多用户表还需修改当前文件中
providers
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], // 增加如下 driver->jwt 'user' => [ 'driver' => 'jwt', 'provider' => 'users', ], ],
最后在
.env
末尾增加如下两条配置有效时间: 是指在x分钟内可以凭借 token 获取内容
刷新时间: 是指在x分钟内可以凭借旧 token 换取新 token , 直到刷新超过刷新时间后, 需重新获取无法再使用旧 token 换取新 token
JWT_TTL=1440 // 有效时间(单位: 分钟) JWT_REFRESH_TTL=20160 // 刷新时间(单位: 分钟)
登录部署
创建控制器
php artisan make:controller Backend/AuthenticationController
创建 request
php artisan make:request Backend/UserRequest
创建 resource
php artisan make:resource Backend/UserResource
编写路由
<?php use App\Http\Controllers\Backend\AuthenticationController; use Illuminate\Support\Facades\Route; /** * 后台免认证路由组 */ Route::prefix('backend')->name('backend.')->group(function () { Route::post('login', [AuthenticationController::class, 'login'])->name('authentication.login'); }); /** * 后台需要认证路由组 */ Route::prefix('backend')->name('backend.')->middleware(["auth:user"])->group(function () { Route::get('refresh', [AuthenticationController::class, 'refresh'])->name('authentication.refresh'); Route::delete('logout', [AuthenticationController::class, 'logout'])->name('authentication.logout'); });
创建辅助函数文件
touch app/helper.php
composer 自动加载
"autoload": { ... "files": [ "app/helper.php" ] },
composer dump-autoload
修改
app/helper.php
增加三个函数, 这个也可以自己封装<?php if (!function_exists('send')) { /** * 请求成功响应,可以返回一个字符串或者一个数组 * @param mixed $message 字符串或者数组 * @param int $status 状态码 * @return \Illuminate\Http\JsonResponse */ function send($message, int $status = 200) { return \Response::json($message, $status); } } if (!function_exists('send_message')) { /** * 字符串响应,用于发送字符串 * @param string $message 内容 * @param int $status 状态码 * @return \Illuminate\Http\JsonResponse */ function send_message($message, int $status = 400, $code = null) { $code = $code ?: $status; return \Response::json(['message' => $message, 'code' => $code], $status); } } if (!function_exists('no_content')) { /** * 空响应 * @param int $status 状态码 * @return \Illuminate\Http\Response */ function no_content(int $status = 204) { return \Response::noContent($status); } }
编写
AuthenticationController
控制器中 登录/刷新/退出 方法<?php namespace App\Http\Controllers\Backend; use App\Http\Controllers\Controller; use App\Http\Requests\Backend\UserRequest; use App\Http\Resources\Backend\UserResource; use App\Models\User; use Illuminate\Http\Response; class AuthenticationController extends Controller { public function login(UserRequest $request) { $username = $request->input('username'); $password = $request->input('password'); $user = User::whereName($username)->first(); if (!$user) { return send_message("账号不存在", Response::HTTP_UNPROCESSABLE_ENTITY); } $token = auth('user')->attempt(compact(['username', 'password'])); if (!$token) { return send_message("账号和密码不匹配", Response::HTTP_UNPROCESSABLE_ENTITY); } return send([ 'token' => $token, 'expire_in' => auth('user')->factory()->getTTL() * 60, 'info' => new UserResource($user) ]); } public function refresh() { $token = auth()->refresh(); return send([ 'token' => $token, 'expire_in' => auth()->factory()->getTTL() * 60, ]); } public function logout() { auth()->logout(); return no_content(); } }
修改中间件
<?php namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; use Illuminate\Http\Response; class Authenticate extends Middleware { /** * Get the path the user should be redirected to when they are not authenticated. * * @param \Illuminate\Http\Request $request * @return string|null */ protected function redirectTo($request) { // if (! $request->expectsJson()) { // return route('login'); // } return send_message('未认证,请先登录', Response::HTTP_UNAUTHORIZED); } }
建议自己捕获一下异常
常用扩展
文件上传
composer require littledragoner/file-manager
Laravel 汉化
composer require overtrue/laravel-lang
枚举类型
composer require bensampo/laravel-enum
本作品采用《CC 协议》,转载必须注明作者和本文链接
jwt-auth好像不维护了,可以考虑用laravel Sanctum