Laravel 登录、认证及授权

登录、认证及授权

令牌方式:

Authorization: Bearer {yourtokenhere}
?token=yourtokenhere
  1. 安装扩展包
$ composer require tymon/jwt-auth
  1. 发布配置文件(限5.5+)
$ php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

这里创建一个 config/jwt.php 文件。

  1. 生成安全密钥
$ php artisan jwt:secret
  1. 配置说明
<?php
/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
return [
    /*
     * |--------------------------------------------------------------------------
     * | JWT认证密钥
     * |--------------------------------------------------------------------------
     * |
     * | Don't forget to set this, as it will be used to sign your tokens.
     * | A helper command is provided for this: `php artisan jwt:generate`
     * |
     */
    
    'secret' => env('JWT_SECRET', 'H3HLg3cuQAmeVN3oLHdcLFWEekP6ceJ5'),

    /*
    |--------------------------------------------------------------------------
    | token有效期(分钟)
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in minutes) that the token will be valid for.
    | Defaults to 1 hour
    |
    */

    'ttl' => 10080,


    /*
    |--------------------------------------------------------------------------
    | 刷新token时间(分钟)
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in minutes) that the token can be refreshed
    | within. I.E. The user can refresh their token within a 2 week window of
    | the original token being created until they must re-authenticate.
    | Defaults to 2 weeks
    |
    */

    'refresh_ttl' => 1440,

    /*
    |--------------------------------------------------------------------------
    | token签名算法
    |--------------------------------------------------------------------------
    |
    | Specify the hashing algorithm that will be used to sign the token.
    |
    | See here: https://github.com/namshi/jose/tree/2.2.0/src/Namshi/JOSE/Signer
    | for possible values
    |
    */

    'algo' => 'HS256',

    /*
    |--------------------------------------------------------------------------
    | 指向用户模型的命名空间路径
    |--------------------------------------------------------------------------
    |
    | Specify the full namespace to your User model.
    | e.g. 'Acme\Entities\User'
    |
    */

    'user' => 'App\Models\User',

    /*
    |--------------------------------------------------------------------------
    | 用于从token的sub中获取用户唯一标识
    |--------------------------------------------------------------------------
    |
    | Specify a unique property of the user that will be added as the 'sub'
    | claim of the token payload.
    |
    */

    'identifier' => 'id',

    /*
    |--------------------------------------------------------------------------
    | 必须出现在token的payload中的选项,否则会抛出TokenInvalidException异常
    |--------------------------------------------------------------------------
    |
    | Specify the required claims that must exist in any token.
    | A TokenInvalidException will be thrown if any of these claims are not
    | present in the payload.
    |
    | 该JWT的签发者
    | 在什么时候签发的token
    | token什么时候过期
    | token在此时间之前不能被接收处理
    | 该JWT所面向的用户
    | JWT ID为web token提供唯一标识
    */

    'required_claims' => [
        'iss',
        'iat',
        'exp',
        'nbf',
        'sub',
        'jti'
    ], 
    
    /*
     * |--------------------------------------------------------------------------
     * | 如果该选项被设置为false,那么我们将不能废止token,即使我们刷新了token,前一个token仍然有效
     * |--------------------------------------------------------------------------
     * |
     * | In order to invalidate tokens, you must have the blacklist enabled.
     * | If you do not want or need this functionality, then set this to false.
     * |
     */
    
    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

    /*
    |--------------------------------------------------------------------------
    | 完成各种任务的具体实现
    |--------------------------------------------------------------------------
    |
    | Specify the various providers used throughout the package.
    |
    */

    'providers' => [
        
        /*
         * |--------------------------------------------------------------------------
         * | 基于sub获取用户的实现
         * |--------------------------------------------------------------------------
         * |
         * | Specify the provider that is used to find the user based
         * | on the subject claim
         * |
         */
        
        'user' => 'Tymon\JWTAuth\Providers\User\EloquentUserAdapter',

        /*
        |--------------------------------------------------------------------------
        | 加密/解密token
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to create and decode the tokens.
        |
        */

        'jwt' => 'Tymon\JWTAuth\Providers\JWT\NamshiAdapter',

        /*
        |--------------------------------------------------------------------------
        | 通过证书/ID获取认证用户
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to authenticate users.
        |
        */

        'auth' => 'Tymon\JWTAuth\Providers\Auth\IlluminateAuthAdapter',

        /*
        |--------------------------------------------------------------------------
        | 存储token直到它们失效
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to store tokens in the blacklist
        |
        */

        'storage' => 'Tymon\JWTAuth\Providers\Storage\IlluminateCacheAdapter'
    ]
];
  1. 修改用户模型
<?php
namespace App\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword, SoftDeletes;

    protected $table = 'users';

    protected $primaryKey = 'id';

    public $timestamps = true;

    protected $guarded = [
        'deleted_at'
    ];

    protected $dates = [
        'created_at',
        'updated_at',
        'deleted_at'
    ];

    protected $hidden = [
        'deleted_at',
        'created_at',
        'updated_at',
        'password'
    ];
}

  1. 创建认证中间件
<?php
namespace App\Http\Middleware;

use Closure;
use Tymon\JWTAuth\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Illuminate\Contracts\Events\Dispatcher;

class AuthToken
{

    // JWTAuth
    protected $auth;

    // 事件
    protected $events;

    /**
     * 创建一个新的实例
     *
     * @param \Tymon\JWTAuth\JWTAuth $auth            
     */
    public function __construct(Dispatcher $events, JWTAuth $auth)
    {
        $this->auth = $auth;
        $this->events = $events;
    }

    /**
     * 前置处理请求
     *
     * @param \Illuminate\Http\Request $request            
     * @param \Closure $next            
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $token = $this->auth->getToken();
        try {
            $user = $this->auth->authenticate($token);
            if (! empty($user->company_id)) {
                // 认证成功
            }
        } catch (TokenExpiredException $e) {
            // token 已过期
            throw new ApiException(ApiException::TOKEN_EXPIRED);
        } catch (JWTException $e) {
            // 无效的token
            throw new ApiException(ApiException::INVALID_TOKEN);
        }
        
        if (! $user) {
            // 用户不存在
            throw new ApiException(ApiException::USER_NOT_EXIST);
        }
        
        $this->events->fire('tymon.jwt.valid', $user);
        return $next($request);
    }
}
  1. 用户认证示例

  2. 获取 token

use Tymon\JWTAuth\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;

try {
    $credentials['username'] = 1;
    $credentials['password'] = 2;
    if (! $token = $this->auth->attempt($where)) {
        // 用户名或密码不正确
        throw new ApiException(ApiException::LOGIN_FAIL);
    }
} catch (JWTException $e) {
    // 创建token失败或api签名失败
}
return $token;
  1. 刷新 token
 try {
    // 更新token
    $token = $this->auth->setToken($oldToken)->refresh();
} catch (TokenExpiredException $e) {
    // token已过期
    throw new ApiException(ApiException::TOKEN_EXPIRED);
} catch (JWTException $e) {
    // 无效的token
    throw new ApiException(ApiException::INVALID_TOKEN);
}

// 将刷新的令牌发送回客户端
// response()->headers->set('Authorization', 'Bearer ' . $token);
return $token;

推荐资料

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容