zoukankan      html  css  js  c++  java
  • larval5.7安装jwt使用

    将包添加到composer.json

    "require": {
        ...
        "tymon/jwt-auth": "1.0.0-rc.3"
    }
    

    然后按命令更新composer

    composer update
    

    设置配置

    生成密钥
    php artisan jwt:secret
    
    发布配置文件
    php artisan vendor:publish --provider="TymonJWTAuthProvidersLaravelServiceProvider"
    
    打开app.php并添加以下行

    在’aliases array’数组中

    'JWTAuth'=> TymonJWTAuthFacadesJWTAuth::class,
    'JWTFactory'=> TymonJWTAuthFacadesJWTFactory::class,
    
    更新用户模型

    打开User.php并为模型实现JWTSubject

    use TymonJWTAuthContractsJWTSubject;
    class User extends Authenticatable implements JWTSubject
    

    并在模型中添加2个方法(在未完成的官方指南中阅读有关这些功能的更多信息)

    public function getJWTIdentifier(){
        return $ this-> getKey();
    }
    public function getJWTCustomClaims(){
        return [];
    }
    
    更新配置auth.php

    打开config/auth.php并将API的保护驱动程序更改为’jwt’(默认为令牌)

    'guards'=> [ 
        ...
        'api'=> [
            'driver'=>'jwt',
            'provider'=>'users',
        ],
    ],
    
    创建登录控制器

    创建controller用于login、logout、refresh等

    <?php
    
    namespace AppHttpControllersAuth;
    
    use IlluminateSupportFacadesAuth;
    use AppHttpControllersController;
    
    class JwtAuthController extends Controller
    {
        /**
         * Create a new AuthController instance.
         * 
         *
         * @return void
         */
        public function __construct()
        {
            $this->middleware('jwt.auth', ['except' => ['login']]);
            // 另外关于上面的中间件,官方文档写的是『auth:api』
            // 但是我推荐用 『jwt.auth』,效果是一样的,但是有更加丰富的报错信息返回
        }
    
        /**
         * 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(auth('api')->user());
        }
    
        /**
         * Log the user out (Invalidate the token).
         *
         * @return IlluminateHttpJsonResponse
         */
        public function logout()
        {
            auth('api')->logout();
    
            return response()->json(['message' => 'Successfully logged out']);
        }
    
        /**
         * Refresh a token.
         * 刷新token,如果开启黑名单,以前的token便会失效。
         * 值得注意的是用上面的getToken再获取一次Token并不算做刷新,两次获得的Token是并行的,即两个都可用。
         * @return IlluminateHttpJsonResponse
         */
        public function refresh()
        {
            return $this->respondWithToken(auth('api')->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' => auth('api')->factory()->getTTL() * 60
            ]);
        }
    }
    
    创建路由

    打开routes/api.php然后添加一些路由

    Route::group(['prefix' => 'auth'], function () {
        Route::post('login', 'Auth\JwtAuthController@login');
        Route::post('logout', 'Auth\JwtAuthController@logout');
        Route::post('refresh', 'Auth\JwtAuthController@refresh');
        Route::post('me', 'Auth\JwtAuthController@me');
    });
    

    然后在标头请求中添加“Authorization:Bearer {token}”

    如果你想捕获异常 在你的app/Exceptions/Handler.php中捕获’render’函数中的错误。

    use SymfonyComponentHttpKernelExceptionUnauthorizedHttpException;
    
    ……
    
    if ($exception instanceof UnauthorizedHttpException) {
        $preException = $exception->getPrevious();
        if ($preException instanceof
                      TymonJWTAuthExceptionsTokenExpiredException) {
            return response()->json(['error' => 'TOKEN_EXPIRED']);
        } else if ($preException instanceof
                      TymonJWTAuthExceptionsTokenInvalidException) {
            return response()->json(['error' => 'TOKEN_INVALID']);
        } else if ($preException instanceof
                 TymonJWTAuthExceptionsTokenBlacklistedException) {
             return response()->json(['error' => 'TOKEN_BLACKLISTED']);
       }
       if ($exception->getMessage() === 'Token not provided') {
           return response()->json(['error' => 'Token not provided']);
       }
    }
    

    验证用户登录

    php artisan make:middleware RefreshToken
    

    中间件代码如下:

    RefreshToken.php

    <?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);
        }
    }
    
  • 相关阅读:
    Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。
    xss跨站脚本和csrf 跨站请求伪造
    随机32位字符
    Demura说明
    Demura介绍
    C# 调用c++编译dll
    数据结构之-数组
    C# 深克隆和浅克隆
    弹性盒子的知识点
    行为型设计模式之-观察者模式
  • 原文地址:https://www.cnblogs.com/zhanghuilong/p/11718020.html
Copyright © 2011-2022 走看看