laravel8配置jwt并支持自动刷新

使用tymon/jwt-auth包(https://packagist.org/packages/tymon/jwt-auth)

1、安装

composer require tymon/jwt-auth

2、发布配置,运行以下命令以发布包配置文件:您现在应该有一个config/jwt.php文件,允许您配置此包的基础知识。

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

3、生成秘钥

php artisan jwt:secret

这将.env使用类似的内容更新您的文件JWT_SECRET=foobar

这是将用于签署您的令牌的密钥。这究竟如何发生将取决于您选择使用的算法。

4、更新您的用户模型

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class TestUser extends Authenticatable implements JWTSubject
{
    use Notifiable;

    public $timestamps = false;

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        // TODO: Implement getJWTIdentifier() method.
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

  

并新建test_user表

CREATE TABLE `test_users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `phone` char(11) COLLATE utf8mb4_general_ci NOT NULL,
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `sex` tinyint NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

5、配置身份验证保护

注意:这仅在您使用 Laravel 5.2 及更高版本时有效。

在该config/auth.php文件中,您需要进行一些更改以配置 Laravel 以使用jwt防护来支持您的应用程序身份验证。

对文件进行以下更改:

'defaults' => [
    'guard' => 'api',
    'passwords' => 'users',
],

...

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

这里我们告诉api守卫使用jwt驱动程序,我们将api守卫设置为默认值。

我们现在可以使用 Laravel 内置的 Auth 系统,由 jwt-auth 完成幕后工作!

6、添加一些路由,使用了auth.jwt自定义的中间件

Route::post('login', [\App\Http\Controllers\TestUserController::class, 'login']);
Route::post('register', [\App\Http\Controllers\TestUserController::class, 'register']);
Route::group(['middleware' => ['auth.jwt']], function () {
    Route::get('logout', [\App\Http\Controllers\TestUserController::class, 'logout']);
    Route::get('user', [\App\Http\Controllers\TestUserController::class, 'getAuthUser']);
    Route::get('refresh', [\App\Http\Controllers\TestUserController::class, 'refresh']);
});

7、创建控制器

php artisan make:controller TestUserController

8、添加以下内容

<?php

namespace App\Http\Controllers;

use App\Http\Response\BizFailResponse;
use App\Http\Response\BizSuccessResponse;
use App\Library\DataChecker;
use App\Models\TestUser;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\JWTAuth;

class TestUserController
{

    public function register(Request $request)
    {
        $params = $request->input();
        DataChecker::requireExpectParamIsNonEmptyStr($params, 'phone');
        DataChecker::requireExpectParamIsNonEmptyStr($params, 'sex');
        DataChecker::requireExpectParamIsNonEmptyStr($params, 'password');
        $userInfo = TestUser::query()->where('phone', $params['phone'])->get()->toArray();
        if (!empty($userInfo)){
            return BizFailResponse::makeWithMsg("该账号{$params['phone']}已被注册");
        }
        $user = new TestUser();
        $user->phone = $params['phone'];
        $user->sex = $params['sex'];
        $user->password = bcrypt($params['password']);
        $user->save();
        return BizSuccessResponse::makeWithData($user);
    }

    public function login(Request $request)
    {
        $input = $request->only('phone', 'password');
        $jwt_token = null;
        if (!$jwt_token = auth()->attempt($input)) {
            return BizFailResponse::makeWithMsg('账号或者密码错误');
        }
        return BizSuccessResponse::makeWithData(['token'=>$jwt_token]);
    }

    public function logout(Request $request)
    {
        try {
            auth()->invalidate();
            return BizSuccessResponse::makeWithMsg('登出成功');
        } catch (JWTException $exception) {
            return BizFailResponse::makeWithMsg('登出失败');
        }
    }

    public function refresh(){
        return BizSuccessResponse::makeWithData(['token'=>auth()->refresh()]);
    }

    public function getAuthUser(Request $request)
    {
        $user = auth()->user();

        return response()->json(['user' => $user]);
    }
}

9、新建中间件,支持token校验和过期自动刷新

php artisan make:middleware AuthJwtTokend  

  代码如下:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;

/**
 * 验证token,并且过期自动刷新
 * Class AuthJwtToken
 * @package App\Http\Middleware
 */
class AuthJwtToken extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {

        $this->checkForToken($request);
        try {
            if ($this->auth->parseToken()->authenticate()){
                return $next($request);
            }
            throw new UnauthorizedHttpException('jwt-auth', '该用户未登录');
        }catch (TokenExpiredException $e){
            try {
                $token = $this->auth->refresh();
                Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
                // 在响应头中返回新的 token
                return $this->setAuthenticationHeader($next($request), $token);
            }catch (JWTException $e) {
                throw new UnauthorizedHttpException('jwt-auth', $e->getMessage());
            }
        }
    }
}

10、注册自定义中间件

App\Http\Kernel中$routeMiddleware新增
// 自定义中间件
'auth.jwt' => AuthJwtToken::class

11、访问注册、登录、登出、获取用户信息等接口

 

上一篇:laravel8 jwt接口安全


下一篇:laravel8自定义错误异常如 {“message“:“Unauthenticated.“}