다음 튜토리얼 칼럼인 laravel에서는 laravel8의 dingo 및 jwt 인증에 대해 소개하겠습니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다!
dingo api 패키지는 laravel 및 lumen용으로 제공되는 Restful 툴킷으로, jwt 구성 요소와 함께 작동하여 사용자 인증을 빠르게 완료하는 동시에 작업 중에 생성되는 데이터 및 예외를 캡처할 수 있습니다. 그에 따라 대응할 수 있습니다.
주요 기능:
laravel 루트 디렉터리에 작곡가를 통해 dingo 확장 패키지를 설치합니다.
composer require dingo/api
다음 명령을 사용하여 API 구성 파일을 구성 파일에 게시합니다.
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
dingo의 api 구성 정보는 .env 파일에서 구성할 수 있습니다
# dingo # API_SUBTYPE —— 项目的简称; API_SUBTYPE=lms # API_PREFIX —— 与 API_DOMAIN 二选一,路由的前缀,例如设置为 api API_PREFIX=api # 定义版本 API_VERSION=v1 # 是否开启调试模式 API_DEBUG=true
에 대한 자세한 구성 dingo 관련 문서를 확인하세요: https://learnku.com/docs/dingo-api/2.0.0/Configuration/1444
jwt는 매우 가볍습니다. 이 사양을 통해 우리는 jwt를 사용하여 사용자와 서버 간에 안전하고 신뢰할 수 있는 정보를 전송할 수 있습니다. 주요 사용 시나리오는 다음과 같습니다. 인증 및 데이터 교환
laravel 루트 디렉터리에 작곡가를 통해 jwt 확장 패키지를 설치합니다. 특정 명령은 다음과 같습니다.
composer require tymon/jwt-auth
다음 명령을 사용하여 API 구성 파일을 구성 파일에 게시합니다.
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
.env 파일에 jwt 암호화 키를 생성합니다. 특정 명령은 다음과 같습니다.
php artisan jwt:secret
config/api.php 구성 수정
'auth' => [ 'jwt' => 'Dingo\Api\Auth\Provider\JWT', ],
config/auth.php 구성 수정
'defaults' => [ #注:这里修改改了默认的配置,默认是web 'guard' => 'api', 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'jwt', 'provider' => 'users', 'hash' => false, ], ],
jwt의 자세한 구성은 관련 문서를 참조하세요: https://jwt-auth.readthedocs.io/en/ 개발/
토큰 만료 새로고침을 위한 RefreshToken 미들웨어 생성
namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; use Illuminate\Http\Request; use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Exceptions\TokenExpiredException; use Tymon\JWTAuth\Http\Middleware\BaseMiddleware; class RefreshToken extends BaseMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle(Request $request, Closure $next) { // 检查此次请求中是否带有 token,如果没有则抛出异常。 $this->checkForToken($request); // 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException 异常 try { // 检测用户的登录状态,如果正常则通过 if ($this->auth->parseToken()->authenticate()) { return $next($request); } throw new UnauthorizedHttpException('jwt-auth', '未登录'); } catch (TokenExpiredException $exception) { // 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中 try { // 刷新用户的 token $token = $this->auth->refresh(); // 使用一次性登录以保证此次请求的成功 Auth::guard('api') ->onceUsingId($this->auth->manager() ->getPayloadFactory() ->buildClaimsCollection() ->toPlainArray()['sub']); } catch (JWTException $exception) { // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。 throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage()); } } // 在响应头中返回新的 token return $this->setAuthenticationHeader($next($request), $token); } }
사용자 모델은 getJWTIdentifier() 및 getJWTCustomClaims()의 두 가지 메소드를 구현해야 합니다.
<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Tymon\JWTAuth\Contracts\JWTSubject; class User extends Authenticatable implements JWTSubject { use Notifiable; public $table = "user"; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password','phone','status','create_time','addr_id' ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ // 'email_verified_at' => 'datetime', ]; /** * 指示是否自动维护时间戳 * * @var bool */ public $timestamps = false; public function getJWTIdentifier() { return $this->getKey(); } public function getJWTCustomClaims() { return []; } } ?>
인증 및 기타 관련 작업을 위한 UserController 생성
<?php namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; use App\Models\User; use Dingo\Api\Routing\Helpers; use Illuminate\Http\Request; class UserController extends Controller { use Helpers; public function __construct() { //除去token验证的方法 $this->middleware('refresh.token', [ 'except' => [ 'login', ], ]); } /**用户登录 * @param Request $request * @return \Illuminate\Http\JsonResponse|void */ public function login(Request $request) { $phone = $request->get('phone'); $user = User::where('phone', $phone)->first(); // //attempt貌似无法验证其他字段,如需用其他字段鉴权使用login() // $credentials = request(['name','password']); // if (!$token = auth()->attempt($credentials)) { // return response()->json(['error' => 'Unauthorized'], 401); // } //只要是user实例就可以通过login鉴权 if (! $token = auth()->login($user)) { return response()->json([ "restful" => false, "message" => "账号错误", ]); } //获取用户信息 $user = $this->user(); $key = "user::info::".$user->id; //Redis缓存用户信息3600秒 Redis::set($key,serialize($user->original),"EX",3600); return $this->respondWithToken($token); } /**获取用户 * Get the authenticated User. * * @return \Illuminate\Http\JsonResponse */ public function user() { 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" => "退出成功"]); } /**用户登录状态刷新 * Refresh a token. * @return \Illuminate\Http\JsonResponse */ public function refresh() { return $this->respondWithToken(auth()->refresh()); } /**返回值 * @param $token * @return array */ protected function respondWithToken($token) { return [ 'access_token' => $token, 'token_type' => 'Bearer', 'expires_in' => auth()->factory()->getTTL() * 60, 'restful' => true ]; } }
위 내용은 laravel8의 dingo 및 jwt 인증 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!