laravel5.4フレームワークjwt-auth APIユーザー認証を実現


laravel5.4フレームワークjwt-auth APIユーザー認証を実現
本文は主にJWT([JSON Web Token])授権メカニズムの前後端分離における応用と実践を紹介し、以下の3つの部分を含む:-JWT原理紹介-JWTの安全性-JWTとVueの使用
1、JWTの原理紹介
1.1、cookie and session
ユーザーの授権は往々にしてCookie+Sessionの方式を採用して、つまり原生の応用の中でブラウザのCookieに対する操作Cookie+Sessionの存在をシミュレートする必要があるのは主にHTTPという無状態プロトコルの下でサーバーがどのようにユーザーを識別するかの問題を解決するためで、その原理はユーザーがログインして検証を通過した後に、サービス側がデータを暗号化してクライアントブラウザのCookieの中に保存することである.同時にサーバーは対応するSession(ファイルまたはDB)を保持する.ユーザーがその後に開始した要求はすべてCookie情報を携帯し、サービス側はCookieに従って対応するSessionを取り戻し、検証を完了し、これが以前に登録したユーザーであることを確認する.その動作原理は以下の図の通りである.
1.2、jwt
JWTは、Auth 0が提案するJSONの暗号化署名による認証を実現するスキームである、符号化後のJWTは、jwtを参照できる文字列のように見える.ioeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ.から3つのセグメントに分けられ、復号化によって得られる.
// 1. Headers
//     (typ)、    (alg);
{
  "alg": "HS256",
  "typ": "JWT"
}
// 2. Claims
//            ;
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
// 3. Signature
//   alg                  ;
//             ,        ;
HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    SECREATE_KEY
)

使用中、サービス側はユーザー登録によって検証した後、Header+Claim情報を暗号化して第3段の署名を得た後、署名をクライアントに返し、後続の要求では、サービス側はユーザー要求に含まれるJWTを復号するだけで、ユーザーに相応の情報を取得することを許可できるかどうかを検証することができ、その原理は下図のように、比較によって明らかである.JWTを使用すると、サービス側がセッションを読み込むステップを省くことができ、RESTfulの仕様に適合します.しかし、クライアント(またはApp側)にとっては、ユーザ認証情報を保存するためには、Cookieまたは同様のメカニズムでローカルに保存する必要がある.したがって、JWTはクライアントCookieではなくサービス側のSessionに取って代わるものであり、もちろんクライアントのローカルストレージについてはHTML 5はCookie以外のより多くの解決策を提供する(localStorage/sessionStorage)では、どのようなストレージ方式を採用しているのか、実はJsの操作から見ると本質的な違いはなく、選択が異なるのはセキュリティの考慮からです.
2、JWTのセキュリティ
ユーザーがこのような敏感な情報を授権するには、セキュリティがまず考慮される要素であることは当然です.ここでは主にJWTの使用時にXSSとXSRFの2つの攻撃をどのように防止するかについて議論する.
XSSはWeb上で最も一般的な脆弱性です(私たちの**学報公式サイトにこの脆弱性があることは言わない=.=)その主な原因は、ユーザーに情報を入力してフィルタリングしないことで、ユーザーが悪意を持って入力されたJsコードは、そのWebページにアクセスする際に実行され、Jsは、現在のWebサイトのドメイン名の下に保存されているCookie情報を読み取ることができる.この攻撃に対しては、CookieでもlocalStorageでも情報が盗まれる可能性があるが、XSSを防ぐことも比較的簡単であり、ユーザが入力したすべての情報をフィルタリングすればよい.また、現在ではCDNサービスが増えているこれにより、サーバトラフィックを節約できますが、この間GithubがGreat Cannonに爆撃されたケースなど、不安全なJsスクリプトを導入する可能性もあります.
もう1つのより厄介なXSRF脆弱性は、主にCookieがドメイン名に従って格納されていることを利用し、あるドメイン名にアクセスするとブラウザがそのドメイン名に保存されているCookie情報を自動的に携帯するという特徴がある.JWTをCookieに格納しようとする場合、サービス側は要求ソースを追加的に検証するか、フォームのコミットにランダム署名を追加し、フォームの処理時に検証する必要があります.
私は、JWTをlocalStorageに保存するスキームを後の例で採用し、リクエスト時にJWTをRequest HeaderのAuthorizationビットに格納します.JWTセキュリティについて詳しくは、次の記事を参照してください.-Where to Store Your JWTs-Cookies vs HTML 5 Web Storage-Use JWT the Right Way!-10 Things You Should Know about Tokens - Where to store JWT in browser? How to protect against CSRF?
3、JWTとVueの使用
3.1インストール
jwt_authの現在の使用バージョンは2.0.*はい、しかし、ここでは1.0の最新版を使用しています.同じようにLaravel 5.4以下のバージョンであれば、最新版を使用することをお勧めします.RC.1以前のバージョンでは、マルチユーザtoken認証のセキュリティに問題がありました.$ composer require tymon/jwt-auth 1.0.*@dev
3.2構成
3.2.1サービスプロバイダの追加
以下の行をconfig/appに追加する.phpファイルproviders配列:
'providers' => [
    ...
    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]

3.3配布プロファイル$ php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
3.4鍵の生成
jwt-authはすでにArtisanコマンドを定義しており、Secret$ php artisan jwt:secretを生成するのに便利です.
この命令はあなたのものです.Envファイルの新しい行JWT_SECRET=secret.
3.5 Auth guardの構成
config/auth.phpファイルではguards/driverをjwtに更新する必要があります.
'defaults' => [
    'guard' => 'api',
    'passwords' => 'users',
],
...
'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

Laravel 5.2以降を使用している場合のみ使用できます.
3.6 Modelの変更
jwt-authをユーザー認証として使用する必要がある場合は、私たちのUserモデルを少し変更し、インタフェースを実現する必要があります.変更されたUserモデルは以下の通りです.


namespace App;

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

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    // Rest omitted for brevity

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

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

3.7構成項目詳細(jwt.php)


return [

    /*
    |--------------------------------------------------------------------------
    | JWT Authentication Secret
    |--------------------------------------------------------------------------
    |
    |        token   secret
    |
    */

    'secret' => env('JWT_SECRET'),

    /*
    |--------------------------------------------------------------------------
    | JWT Authentication Keys
    |--------------------------------------------------------------------------
    |
    |      .env        JWT_SECRET       
    |    jwt               token
    |        ,  jwt                   token
    |
    */

    'keys' => [

        /*
        |--------------------------------------------------------------------------
        | Public Key
        |--------------------------------------------------------------------------
        |
        |   
        |
        */

        'public' => env('JWT_PUBLIC_KEY'),

        /*
        |--------------------------------------------------------------------------
        | Private Key
        |--------------------------------------------------------------------------
        |
        |   
        |
        */

        'private' => env('JWT_PRIVATE_KEY'),

        /*
        |--------------------------------------------------------------------------
        | Passphrase
        |--------------------------------------------------------------------------
        |
        |      。       ,    null。
        |
        */

        'passphrase' => env('JWT_PASSPHRASE'),

    ],

    /*
    |--------------------------------------------------------------------------
    | JWT time to live
    |--------------------------------------------------------------------------
    |
    |    access_token        (      ),   1  ,          ,          
    |
    */

    'ttl' => env('JWT_TTL', 60),

    /*
    |--------------------------------------------------------------------------
    | Refresh time to live
    |--------------------------------------------------------------------------
    |
    |    access_token         (      )。       2  。
    |               access_token,          access_token 
    |        access_token,   2      ,         ,      。
    |
    */

    'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),

    /*
    |--------------------------------------------------------------------------
    | JWT hashing algorithm
    |--------------------------------------------------------------------------
    |
    |                  。
    |
    */

    'algo' => env('JWT_ALGO', 'HS256'),

    /*
    |--------------------------------------------------------------------------
    | Required Claims
    |--------------------------------------------------------------------------
    |
    |                。
    | 
    |
    */

    'required_claims' => [
        'iss',
        'iat',
        'exp',
        'nbf',
        'sub',
        'jti',
    ],

    /*
    |--------------------------------------------------------------------------
    | Persistent Claims
    |--------------------------------------------------------------------------
    |
    |                 。
    |
    */

    'persistent_claims' => [
        // 'foo',
        // 'bar',
    ],

    /*
    |--------------------------------------------------------------------------
    | Blacklist Enabled
    |--------------------------------------------------------------------------
    |
    |        ,        。
    |             ,       false。
    |
    */

    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

    /*
    | -------------------------------------------------------------------------
    | Blacklist Grace Period
    | -------------------------------------------------------------------------
    |
    |             JWT   ,
    |    access_token     ,         
    |                      。
    |
    */

    'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),

    /*
    |--------------------------------------------------------------------------
    | Providers
    |--------------------------------------------------------------------------
    |
    |                。
    |
    */

    'providers' => [

        /*
        |--------------------------------------------------------------------------
        | JWT Provider
        |--------------------------------------------------------------------------
        |
        |                 。
        |
        */

        'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,

        /*
        |--------------------------------------------------------------------------
        | Authentication Provider
        |--------------------------------------------------------------------------
        |
        |                   。
        |
        */

        'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,

        /*
        |--------------------------------------------------------------------------
        | Storage Provider
        |--------------------------------------------------------------------------
        |
        |                   。
        |
        */

        'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,

    ],

];

参照リンク:Laravel 5.5 Jwt-Authを用いてAPIユーザ認証及び無痛リフレッシュアクセストークンjwtを実現する.io JWTの前後端分離における応用と実践