Laravel 配合 jwt 使用

测试使用的是Laravel5.5版本。

安装

composer require tymon/jwt-auth=1.0.0-rc.5

配置

生成配置

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

php artisan jwt:secret

auth配置

<?php

return [
    ...

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


    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        // 使用jwt
        'api' => [
            'driver' => 'jwt',
            'provider' => 'apiUser',
        ],
    ],


    'providers' => [
        ...
        // 指定model
        'apiUser' => [
            'driver' => 'eloquent',
            'model' => App\ApiUser::class,
        ],    
    ],
];

编码

控制器:

<?php

namespace App\Http\Controllers\Api;

use App\ApiUser;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;

class AuthController extends Controller
{
    /**
     * 中间件去除login和refresh
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login','refresh']]);
    }

    /**
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $credentials = $request->only('phone', 'password');

        if (count($credentials) < 2) {
            return response()->json(['error' => 'Unauthorized'], 401);
        } 

        $user = ApiUser::where('phone', $credentials['phone'])
            ->where('password', md5($credentials['password']))
            ->first();
        if (empty($user) || !$token = JWTAuth::fromUser($user)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        // dd($token);

        return $this->respondWithToken($token);
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json(auth('api')->user());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth()->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(auth('api')->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ]);
    }
}

路由:

此处注意,我为了方便测试,使用了get方法,生产环境不建议使用get。
// routes/api.php

Route::middleware('api')->prefix('auth')->namespace('Api')->group(function () {
    Route::get('login', 'AuthController@login');
    Route::post('logout', 'AuthController@logout');
    Route::get('refresh', 'AuthController@refresh');
    Route::get('me', 'AuthController@me');
});

测试一下:

Laravel
Laravel
Laravel

unauthenticated处理

这里需要注意下,unauthenticated处理一下比较好,否则会默认跳转login登录页面。

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Auth\AuthenticationException;

class Handler extends ExceptionHandler
{
    ...

    protected function unauthenticated($request, AuthenticationException $exception)
    {
        return response()->json(['message' => 'Unauthenticated.'], 401);
         /*非api可以这么处理
        return $request->expectsJson()
                    ? response()->json(['message' => 'Unauthenticated.'], 401)
                    : redirect()->guest(route('login'));
                    */
    }
}

加入token refresh

加入中间件代码:

<?php
namespace App\Http\Middleware;
  
use Closure;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Illuminate\Auth\AuthenticationException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Illuminate\Http\Exceptions\HttpResponseException;
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, Closure $next)
    {  
        try{
            //检查请求中是否带有token 如果没有token值则抛出异常
            $this->checkForToken($request); 
            if ($request->user = JWTAuth::parseToken()->authenticate()) {       
                return $next($request);
            }
            throw new AuthenticationException('Unauthorized', []);
        }catch (TokenExpiredException $exception){
            //返回特殊的code
            throw new HttpResponseException(response()->json([
                'message' => 'token expired'
            ]));
        } catch (\Exception $exception) {
            throw new AuthenticationException('Unauthorized', []);
        }
    }
}

注册:

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    ...
    protected $routeMiddleware = [
        'token.refresh' => \App\Http\Middleware\RefreshToken::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    ];
}

相应的控制器构造函数修改:

public function __construct()
{
        $this->middleware('token.refresh', ['except' => ['login','refresh']]);
}

把token时间设置成1分钟,测试一下。

Laravel 配合 jwt 使用

可以根据api返回,去调用刷新接口。

简单使用就是这样啦。更多使用可以看下站内其他文章:
JWT 完整使用详解
jwt-auth文档


关注和赞赏都是对小欧莫大的支持

43 声望
1 粉丝
0 条评论
推荐阅读
go 酷之 logrus 日志
更多文章:[链接]引言作为 github 上 golang star 最多的库,logrus值得练习。项目地址项目地址: [链接] [star:21.4k]使用场景日志打印、格式化日志安装go get github.com/sirupsen/logrus常用方法Info 打印 inf...

开源到阅读 760

封面图
Laravel常用代码合集
用Laravel也有不短的时间了,也用过不少版本了,以下代码是在日常项目中收集,作为笔记,也分享出来,希望对你有点用处。注:版本没标注,若有不兼容的问题,微调即可。

开源到1阅读 1.5k

JWT 登录认证
🎈 Token 认证流程作为目前最流行的跨域认证解决方案,JWT(JSON Web Token) 深受开发者的喜爱,主要流程如下:客户端发送账号和密码请求登录服务端收到请求,验证账号密码是否通过验证成功后,服务端会生成唯一...

tiny极客2阅读 984评论 1

封面图
Eloquent ORM 的 where 查询条件的解析器增强版
个人感觉 Eloquent ORM 的 where 条件解析场景并不是那么的丰富,很多条件的拼装都需要引入额外的 orWhere, whereNotIn, whereBetween, whereNotBetween 来辅助完成。这样在做一些抽象的底层查询方法时,不是很友...

big_cat1阅读 1.7k

go使用golang-jwt/jwt入门教程
我们使用 NewWithClaims(method SigningMethod, claims Claims) *Token来生成token,官方的源码如下

海生阅读 757

laravel 文档摘要2
数据库对于数据的保存数据库第一二三范式到底在说什么[链接]数据库的操作独立于 query builder 和 ORM 的存在ORM 的操作是在操作内存对象 是独立的ORM 的一个对象自带了操作 relationship 的方法query builder 的...

changsj阅读 524

Goravel ORM 新增模型关联,用 Golang 写关联也可以跟 Laravel 简单
Goravel 是一个功能完备、具有良好扩展能力的 Web 应用程序框架。作为一个起始脚手架帮助 Golang 开发者快速构建自己的应用。框架风格与 Laravel 保持一致,让 PHPer 不用学习新的框架,也可以愉快的玩转 Golang!

韩同学的简单逻辑阅读 520

43 声望
1 粉丝
宣传栏