zoukankan      html  css  js  c++  java
  • laravel安装jwt-auth及验证(实例)

    laravel 安装jwt-auth及验证

    1、使用composer安装jwt,cmd到项目文件夹中;

    composer require tymon/jwt-auth 1.0.*(这里版本号根据自己的需要写)

    安装jwt ,参考官方文档

    2、如果laravel版本低于5.4

    打开根目录下的config/app.php

    在'providers'数组里加上TymonJWTAuthProvidersLaravelServiceProvider::class,

    'providers' => [ ... TymonJWTAuthProvidersLaravelServiceProvider::class,]

    3、在 config 下增加一个 jwt.php 的配置文件

    php artisan vendor:publish --provider="TymonJWTAuthProvidersLaravelServiceProvider"

    4、在 .env 文件下生成一个加密密钥,如:JWT_SECRET=foobar

    php artisan jwt:secret

    5、在user模型中写入下列代码

    <?php
    namespace AppModel;
    use TymonJWTAuthContractsJWTSubject;
    use IlluminateNotificationsNotifiable;
    use IlluminateFoundationAuthUser as Authenticatable;
    class User extends Authenticatable implements JWTSubject
    {
     // Rest omitted for brevity
     protected $table="user";
     public $timestamps = false;
     public function getJWTIdentifier()
     {
     return $this->getKey();
     }
     public function getJWTCustomClaims()
     {
     return [];
     }
    }
    

      

    6、注册两个 Facade

    config/app.php

    'aliases' => [
     ...
     // 添加以下两行
     'JWTAuth' => 'TymonJWTAuthFacadesJWTAuth',
     'JWTFactory' => 'TymonJWTAuthFacadesJWTFactory',
    ],
    

      

    7、修改 auth.php

    config/auth.php

    'guards' => [
     'web' => [
     'driver' => 'session',
     'provider' => 'users',
     ],
     'api' => [
     'driver' => 'jwt',      // 原来是 token 改成jwt
     'provider' => 'users',
     ],
    ],
    

      

    8、注册路由

    Route::group([
     'prefix' => 'auth'
    ], function ($router) {
     $router->post('login', 'AuthController@login');
     $router->post('logout', 'AuthController@logout');
    });
    

      

    9、创建token控制器

    php artisan make:controller AuthController

    代码如下:

    <?php
    namespace AppHttpControllers;
    use AppModelUser;
    use IlluminateHttpRequest;
    use TymonJWTAuthFacadesJWTAuth;
    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 IlluminateHttpJsonResponse
     */
     public function login()
     {
     $credentials = request(['email', 'password']);
     if (! $token = auth('api')->attempt($credentials)) {
     return response()->json(['error' => 'Unauthorized'], 401);
     }
     return $this->respondWithToken($token);
     }
     /**
     * Get the authenticated User.
     *
     * @return IlluminateHttpJsonResponse
     */
     public function me()
     {
     return response()->json(JWTAuth::parseToken()->touser());
     }
     /**
     * Log the user out (Invalidate the token).
     *
     * @return IlluminateHttpJsonResponse
     */
     public function logout()
     {
     JWTAuth::parseToken()->invalidate();
     return response()->json(['message' => 'Successfully logged out']);
     }
     /**
     * Refresh a token.
     *
     * @return IlluminateHttpJsonResponse
     */
     public function refresh()
     {
     return $this->respondWithToken(JWTAuth::parseToken()->refresh());
     }
     /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return IlluminateHttpJsonResponse
     */
     protected function respondWithToken($token)
     {
     return response()->json([
     'access_token' => $token,
     'token_type' => 'bearer',
     'expires_in' => JWTAuth::factory()->getTTL() * 60
     ]);
     }
    }
    

      

    注意:attempt 一直返回false,是因为password被加密了,使用bcrypt或者password_hash加密后就可以了

    10、验证token获取用户信息

    有两种使用方法:

    加到 url 中:?token=你的token

    加到 header 中,建议用这种,因为在 https 情况下更安全:Authorization:Bearer 你的token

    11、首先使用artisan命令生成一个中间件,我这里命名为RefreshToken.php,创建成功后,需要继承一下JWT的BaseMiddleware

    代码如下:

    <?php
    namespace AppHttpMiddleware;
    use Auth;
    use Closure;
    use TymonJWTAuthExceptionsJWTException;
    use TymonJWTAuthHttpMiddlewareBaseMiddleware;
    use TymonJWTAuthExceptionsTokenExpiredException;
    use SymfonyComponentHttpKernelExceptionUnauthorizedHttpException;
    // 注意,我们要继承的是 jwt 的 BaseMiddleware
    class RefreshToken extends BaseMiddleware
    {
     /**
     * Handle an incoming request.
     *
     * @ param  IlluminateHttpRequest $request
     * @ param  Closure $next
     *
     * @ throws SymfonyComponentHttpKernelExceptionUnauthorizedHttpException
     *
     * @ return mixed
     */
     public function handle($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);
     }
    }
    

      

    这里主要需要说的就是在token进行刷新后,不但需要将token放在返回头中,最好也将请求头中的token进行置换,因为刷新过后,请求头中的token就已经失效了,如果接口内的业务逻辑使用到了请求头中的token,那么就会产生问题。

    这里使用

    $request->headers->set('Authorization','Bearer '.$token);
    

      

    将token在请求头中刷新。

    创建并且写完中间件后,只要将中间件注册,并且在AppExceptionsHandler.php内加上一些异常处理就ok了。

    12、kernel.php文件中

    $routeMiddleware 添加中间件配置

    'RefreshToken' => AppHttpMiddlewareRefreshToken::class,
    

      

    13、添加路由

    Route::group(['prefix' => 'user'],function($router) {
     $router->get('userInfo','UserController@userInfo')->middleware('RefreshToken');
    });
    

      

    在控制器中通过 JWTAuth::user();就可以获取用户信息

    更多PHP内容请访问:

    腾讯T3-T4标准精品PHP架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新)

  • 相关阅读:
    使用javap分析Java的字符串操作
    使用javap深入理解Java整型常量和整型变量的区别
    分享一个WebGL开发的网站-用JavaScript + WebGL开发3D模型
    Java动态代理之InvocationHandler最简单的入门教程
    Java实现 LeetCode 542 01 矩阵(暴力大法,正反便利)
    Java实现 LeetCode 542 01 矩阵(暴力大法,正反便利)
    Java实现 LeetCode 542 01 矩阵(暴力大法,正反便利)
    Java实现 LeetCode 541 反转字符串 II(暴力大法)
    Java实现 LeetCode 541 反转字符串 II(暴力大法)
    Java实现 LeetCode 541 反转字符串 II(暴力大法)
  • 原文地址:https://www.cnblogs.com/a609251438/p/12983719.html
Copyright © 2011-2022 走看看