シングルページアプリケーション、モバイルアプリケーション、RESTful APIサービスの人気が高まるにつれ、 Web開発者 バックエンドコードの記述が大幅に変更されました。 AngularJSやBackboneJSなどのテクノロジーにより、マークアップの構築に多くの時間を費やす必要がなくなり、代わりにフロントエンドアプリケーションが使用するAPIを構築しています。私たちのバックエンドはビジネスロジックとデータに関するものですが、プレゼンテーションロジックはフロントエンドまたはモバイルアプリケーションにのみ移動されます。これらの変更により、最新のアプリケーションに認証を実装する新しい方法が生まれました。
認証は、Webアプリケーションの最も重要な部分の1つです。何十年もの間、Cookieとサーバーベースの認証が最も簡単なソリューションでした。ただし、最新のモバイルおよびシングルページアプリケーションで認証を処理するのは難しい場合があり、より良いアプローチが必要になります。 APIの認証問題に対する最もよく知られている解決策は、 OAuth 2.0 そしてその JSONWebトークン (JWT)。
このJSONWeb Tokenチュートリアルに入る前に、JWTとは正確には何ですか?
JSON Web Tokenは、デジタル署名によって検証および信頼できる情報を送信するために使用されます。コンパクトでURLセーフなJSONオブジェクトで構成されており、その信頼性を検証するために暗号で署名されています。また、ペイロードに機密情報が含まれている場合は暗号化することもできます。
コンパクトな構造のため、JWTは通常HTTPで使用されますAuthorization
ヘッダーまたはURLクエリパラメータ。
JWTは、次のシーケンスとして表されます。 base64url ピリオド文字で区切られたエンコードされた値。
JWTトークンの例を次に示します。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0. yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw
ヘッダーにはトークンのメタデータが含まれ、署名のタイプと暗号化アルゴリズムは最小限で含まれています。 (あなたは使用することができます JSONフォーマッター JSONオブジェクトを美しくするためのツール。)
ヘッダーの例
{ 'alg': 'HS256', 'typ': 'JWT' }
このJWTサンプルヘッダーは、エンコードされたオブジェクトがJSON Webトークンであり、HMACSHA-256アルゴリズムを使用して署名されていることを宣言します。
これがbase64でエンコードされると、JWTの最初の部分ができます。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
JWTのコンテキストでは、クレームは、エンティティ(通常はユーザー)に関するステートメント、およびトークン自体に関する追加のメタデータとして定義できます。クレームには、送信する情報と、サーバーがJSONWebトークン認証を適切に処理するために使用できる情報が含まれています。私たちが提供できる主張は複数あります。これらには、登録されたクレーム名、パブリッククレーム名、およびプライベートクレーム名が含まれます。
登録されたJWTクレーム
これらは、に登録されているクレームです。 IANA JSONWebトークンクレームレジストリ 。これらのJWTクレームは必須ではなく、一連の有用で相互運用可能なクレームの開始点を提供することを目的としています。
これらには以下が含まれます:
パブリッククレーム
公の主張には、衝突耐性のある名前を付ける必要があります。名前をURIまたはURNにすることで、送信者と受信者が閉じたネットワークの一部ではないJWTの名前の衝突が回避されます。
パブリッククレーム名の例は次のようになります:https://www.toptal.com/jwt_claims/is_admin
、ベストプラクティスは、ドキュメントのために逆参照できるように、クレームを説明するファイルをその場所に配置することです。
プライベートクレーム
プライベートクレーム名は、企業内など、既知のシステム間でJWTが閉じた環境でのみ交換される場所で使用できます。これらは、ユーザーID、ユーザーロール、その他の情報など、自分で定義できるという主張です。
クローズドシステムまたはプライベートシステムの外部で意味が矛盾する可能性のあるクレーム名を使用すると、衝突する可能性があるため、注意して使用してください。
Webトークンをできるだけ小さくしたいので、パブリックおよびプライベートクレーム内で必要なデータのみを使用することに注意することが重要です。
JWTのペイロードの例
{ 'iss': 'toptal.com', 'exp': 1426420800, 'https://www.toptal.com/jwt_claims/is_admin': true, 'company': 'ApeeScape', 'awesome': true }
このペイロードの例には、2つの登録済みクレーム、1つのパブリッククレームと2つのプライベートクレームがあります。 base64でエンコードされると、JWTの2番目の部分ができます。
eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0
JWT標準は、JSON Web Signature(JWS)仕様に従って、最終的な署名付きトークンを生成します。これは、エンコードされたJWTヘッダーとエンコードされたJWTペイロードを組み合わせ、HMACSHA-256などの強力な暗号化アルゴリズムを使用して署名することで生成されます。署名の秘密鍵はサーバーによって保持されているため、既存のトークンを検証して新しいトークンに署名することができます。
$encodedContent = base64UrlEncode(header) + '.' + base64UrlEncode(payload); $signature = hashHmacSHA256($encodedContent);
これにより、JWTの最後の部分が得られます。
yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw
man-in-the-middle攻撃を防ぐために、TLS / SSLをJWTと組み合わせて使用することが重要です。ほとんどの場合、機密情報が含まれている場合、これでJWTペイロードを暗号化できます。ただし、保護のレイヤーを追加する場合は、を使用してJWTペイロード自体を暗号化できます。 JSONWeb暗号化 (PLAY)仕様。
もちろん、JWEを使用することによる追加のオーバーヘッドを回避したい場合、別のオプションは、機密情報をデータベースに保持し、機密データにアクセスする必要があるときはいつでも、サーバーへの追加のAPI呼び出しにトークンを使用することです。
JWT認証を使用するすべての利点を確認する前に、過去に認証が行われた方法を確認する必要があります。
HTTPプロトコルはステートレスであるため、ユーザー情報を格納するメカニズムと、ログイン後の後続のすべての要求でユーザーを認証する方法が必要です。ほとんどのWebサイトは、ユーザーのセッションIDを保存するためにCookieを使用しています。
使い方
ブラウザは、ユーザーのIDとパスワードを含むPOSTリクエストをサーバーに送信します。サーバーは、ユーザーのブラウザに設定され、ユーザーを識別するためのセッションIDを含むCookieで応答します。
ユーザーデータはサーバーに保存されるため、後続のすべての要求で、サーバーはそのセッションを見つけて逆シリアル化する必要があります。
スケーリングが難しい :サーバーは、ユーザーのセッションを作成し、サーバー上のどこかに永続化する必要があります。これは、メモリまたはデータベースで実行できます。分散システムを使用している場合は、アプリケーションサーバーに結合されていない別のセッションストレージを使用していることを確認する必要があります。
クロスオリジンリクエストシェアリング(CORS) :AJAX呼び出しを使用して別のドメイン(「クロスオリジン」)からリソースをフェッチする場合、デフォルトではHTTPリクエストにクロスオリジンリクエストのCookieが含まれていないため、禁止されたリクエストで問題が発生する可能性があります。
Webフレームワークとの結合 :サーバーベースの認証を使用する場合、フレームワークの認証スキームに関連付けられます。異なるプログラミング言語で書かれた異なるWebフレームワーク間でセッションデータを共有することは、本当に難しいか、不可能ですらあります。
トークンベース/ JWT認証はステートレスであるため、セッションにユーザー情報を保存する必要はありません。これにより、ユーザーがどこにログインしたかを気にせずにアプリケーションを拡張できます。同じトークンを使用して、ログインしているドメイン以外のドメインから安全なリソースを簡単にフェッチできます。
JSONWebトークンのしくみ
ブラウザまたはモバイルクライアントは、ユーザーのログイン情報を含む認証サーバーに要求を出します。認証サーバーは新しいJWTアクセストークンを生成し、それをクライアントに返します。制限されたリソースへのすべての要求で、クライアントはクエリ文字列またはAuthorization
でアクセストークンを送信しますヘッダ。次に、サーバーはトークンを検証し、トークンが有効な場合は、安全なリソースをクライアントに返します。
認証サーバーは、任意の安全な署名方法を使用してトークンに署名できます。たとえば、すべての関係者間で秘密鍵を共有するための安全なチャネルがある場合は、HMACSHA-256などの対称鍵アルゴリズムを使用できます。あるいは、RSAなどの非対称の公開鍵システムを使用して、さらに鍵を共有する必要をなくすこともできます。
ステートレス、スケーリングが容易 :トークンには、ユーザーを識別するためのすべての情報が含まれているため、セッション状態は不要です。ロードバランサーを使用すると、ログオンした同じサーバーにバインドされる代わりに、ユーザーを任意のサーバーに渡すことができます。
再利用性 :複数のプラットフォームとドメインで実行され、ユーザーの認証に同じトークンを再利用する、多数の個別のサーバーを使用できます。別のアプリケーションと権限を共有するアプリケーションを作成するのは簡単です。
JWTセキュリティ :Cookieを使用していないため、クロスサイトリクエストフォージェリ(CSRF)攻撃から保護する必要はありません。機密情報をトークンに入れる必要がある場合は、JWEを使用してトークンを暗号化し、中間者攻撃を防ぐためにHTTPS経由でトークンを送信する必要があります。
パフォーマンス :各リクエストでセッションを見つけて逆シリアル化するサーバー側のルックアップはありません。トークンを検証してその内容を解析するために、HMACSHA-256を計算するだけです。
コールオプション価格の計算方法
このJWTチュートリアルでは、2つの一般的なWebテクノロジーでJSON Web Tokenを使用して基本認証を実装する方法を示します。バックエンドコード用のLaravel5とフロントエンドシングルページアプリケーション(SPA)の例用のAngularJSです。 (デモ全体を見つけることができます ここに 、およびのソースコード このGitHubリポジトリ チュートリアルに従うことができるように。)
このJSONWebトークンの例では、クレームで送信される情報の機密性を確保するために、いかなる種類の暗号化も使用しません。実際には、TLS / SSLが要求を暗号化するため、これは多くの場合問題ありません。ただし、トークンにユーザーの社会保障番号などの機密情報が含まれる場合は、JWEを使用して暗号化する必要もあります。
Laravelを使用してユーザー登録を処理し、ユーザーデータをデータベースに永続化し、Angularアプリが消費するために認証を必要とするいくつかの制限されたデータを提供します。クロスオリジンリソースシェアリング(CORS)もシミュレートするためのサンプルAPIサブドメインを作成します。
インストールとプロジェクトのブートストラップ
Laravelを使用するには、をインストールする必要があります 作曲 私たちのマシンのパッケージマネージャー。 Laravelで開発するときは、VagrantのLaravelHomesteadパッケージ済み「ボックス」を使用することをお勧めします。オペレーティングシステムに関係なく、完全な開発環境を提供します。
JWT Laravelアプリケーションをブートストラップする最も簡単な方法は、ComposerパッケージのLaravelインストーラーを使用することです。
composer global require 'laravel/installer=~1.1'
これで、laravel new jwt
を実行して新しいLaravelプロジェクトを作成する準備が整いました。
このプロセスに関する質問については、公式を参照してください Laravelのドキュメント 。
基本的なLaravel5アプリケーションを作成したら、Homestead.yaml
をセットアップする必要があります。これにより、ローカル環境のフォルダーマッピングとドメイン構成が構成されます。
Homestead.yaml
の例ファイル:
--- ip: '192.168.10.10' memory: 2048 cpus: 1 authorize: /Users/ttkalec/.ssh/public.psk keys: - /Users/ttkalec/.ssh/private.ppk folders: - map: /coding/jwt to: /home/vagrant/coding/jwt sites: - map: jwt.dev to: /home/vagrant/coding/jwt/public - map: api.jwt.dev to: /home/vagrant/coding/jwt/public variables: - key: APP_ENV value: local
Vagrantボックスをvagrant up
で起動した後コマンドを実行し、vagrant ssh
を使用してログインすると、以前に定義したプロジェクトディレクトリに移動します。上記の例では、これは/home/vagrant/coding/jwt
になります。これでphp artisan migrate
を実行できますデータベースに必要なユーザーテーブルを作成するためのコマンド。
Composerの依存関係のインストール
幸い、Laravelに取り組んでいて、アプリケーションを再利用および拡張できる多くの優れたパッケージを維持している開発者のコミュニティがあります。この例では、 tymon/jwt-auth
、Sean Tymonによる、サーバー側でトークンを処理するため、および barryvdh/laravel-cors
、Barryvdによる。 Heuvel、CORSを処理するため。
jwt-auth
tymon/jwt-auth
が必要composer.json
のパッケージ依存関係を更新します。
composer require tymon/jwt-auth 0.5.*
JWTAuthServiceProvider
を追加しますapp/config/app.php
へプロバイダー配列。
'TymonJWTAuthProvidersJWTAuthServiceProvider'
次に、app/config/app.php
でファイル、aliases
の下配列、JWTAuth
を追加しますファサード。
'JWTAuth' => 'TymonJWTAuthFacadesJWTAuth'
最後に、次のコマンドを使用してパッケージ構成を公開します。phpartisan config:publish tymon / jwt-auth
JSON Webトークンは、秘密鍵を使用して暗号化されます。 php artisan jwt:generate
を使用してそのキーを生成できますコマンド。 config/jwt.php
内に配置されますファイル。ただし、実稼働環境では、構成ファイル内にパスワードやAPIキーを含める必要はありません。代わりに、それらをサーバー環境変数内に配置し、構成ファイルでenv
を使用して参照する必要があります。関数。例えば:
'secret' => env('JWT_SECRET')
このパッケージとそのすべての構成設定について詳しく知ることができます Githubで 。
laravel-cors
barryvdh/laravel-cors
が必要composer.json
のパッケージ依存関係を更新します。
composer require barryvdh/laravel-cors [email protected]
CorsServiceProvider
を追加しますapp/config/app.php
へプロバイダー配列。
'BarryvdhCorsCorsServiceProvider'
次に、ミドルウェアをapp/Http/Kernel.php
に追加します。
'BarryvdhCorsMiddlewareHandleCors'
構成をローカルに公開するconfig/cors.php
php artisan vendor:publish
を使用してファイルコマンド。
cors.php
の例ファイル構成:
return [ 'defaults' => [ 'supportsCredentials' => false, 'allowedOrigins' => [], 'allowedHeaders' => [], 'allowedMethods' => [], 'exposedHeaders' => [], 'maxAge' => 0, 'hosts' => [], ], 'paths' => [ 'v1/*' => [ 'allowedOrigins' => ['*'], 'allowedHeaders' => ['*'], 'allowedMethods' => ['*'], 'maxAge' => 3600, ], ], ];
HTTPリクエストのルーティングと処理
簡潔にするために、Laravelのルーティングとコントローラーへのリクエストの委任を担当するroutes.phpファイル内にすべてのコードを配置します。通常、すべてのHTTPリクエストを処理するための専用コントローラーを作成し、コードをモジュール化してクリーンに保ちます。
を使用してAngularJSSPAビューをロードします
Route::get('/', function () { return view('spa'); });
ユーザー登録
POST
を作成するとき/signup
へのリクエストユーザー名とパスワードを使用して、新しいユーザーを作成し、データベースに保存しようとします。ユーザーが作成された後、JWTが作成され、JSON応答を介して返されます。
Route::post('/signup', function () { $credentials = Input::only('email', 'password'); try { $user = User::create($credentials); } catch (Exception $e) { return Response::json(['error' => 'User already exists.'], HttpResponse::HTTP_CONFLICT); } $token = JWTAuth::fromUser($user); return Response::json(compact('token')); });
ユーザーサインイン
POST
を作成するとき/signin
へのリクエストユーザー名とパスワードを使用して、ユーザーが存在することを確認し、JSON応答を介してJWTを返します。
Route::post('/signin', function () { $credentials = Input::only('email', 'password'); if ( ! $token = JWTAuth::attempt($credentials)) { return Response::json(false, HttpResponse::HTTP_UNAUTHORIZED); } return Response::json(compact('token')); });
同じドメインで制限付きリソースを取得する
ユーザーがサインインすると、制限されたリソースを取得できます。ルートを作成しました/restricted
これは、認証されたユーザーを必要とするリソースをシミュレートします。これを行うには、リクエストAuthorization
ヘッダーまたはクエリ文字列は、バックエンドが検証するためのJWTを提供する必要があります。
Route::get('/restricted', [ 'before' => 'jwt-auth', function () { $token = JWTAuth::getToken(); $user = JWTAuth::toUser($token); return Response::json([ 'data' => [ 'email' => $user->email, 'registered_at' => $user->created_at->toDateTimeString() ] ]); } ]);
この例では、jwt-auth
を使用していますjwt-auth
で提供されるミドルウェア'before' => 'jwt-auth'
を使用したパッケージ。このミドルウェアは、リクエストをフィルタリングし、JWTトークンを検証するために使用されます。トークンが無効、存在しない、または期限切れの場合、ミドルウェアはキャッチできる例外をスローします。
Laravel 5では、app/Exceptions/Handler.php
を使用して例外をキャッチできますファイル。 render
を使用するスローされた例外に基づいてHTTP応答を作成できる関数。
public function render($request, Exception $e) { if ($e instanceof TymonJWTAuthExceptionsTokenInvalidException) { return response(['Token is invalid'], 401); } if ($e instanceof TymonJWTAuthExceptionsTokenExpiredException) { return response(['Token has expired'], 401); } return parent::render($request, $e); }
ユーザーが認証され、トークンが有効な場合、JSONを介して制限されたデータをフロントエンドに安全に返すことができます。
APIサブドメインから制限付きリソースを取得する
次のJSONWebトークンの例では、トークンの検証に別のアプローチを採用します。 jwt-auth
を使用する代わりにミドルウェアの場合、例外を手動で処理します。 POST
を作成するときAPIサーバーへのリクエストapi.jwt.dev/v1/restricted
、クロスオリジンリクエストを行っているため、バックエンドでCORSを有効にする必要があります。幸い、config/cors.php
ですでにCORSを設定しています。ファイル。
Route::group(['domain' => 'api.jwt.dev', 'prefix' => 'v1'], function () { Route::get('/restricted', function () { try { JWTAuth::parseToken()->toUser(); } catch (Exception $e) { return Response::json(['error' => $e->getMessage()], HttpResponse::HTTP_UNAUTHORIZED); } return ['data' => 'This has come from a dedicated API subdomain with restricted access.']; }); });
AngularJSをフロントエンドとして使用しており、ユーザー認証とサンプルデータ用のLaravelバックエンド認証サーバーへのAPI呼び出しと、クロスオリジンのサンプルデータ用のAPIサーバーに依存しています。プロジェクトのホームページにアクセスすると、バックエンドがresources/views/spa.blade.php
を提供します。 Angularアプリケーションをブートストラップするビュー。
Angularアプリのフォルダー構造は次のとおりです。
public/ |-- css/ `-- bootstrap.superhero.min.css |-- lib/ |-- loading-bar.css |-- loading-bar.js `-- ngStorage.js |-- partials/ |-- home.html |-- restricted.html |-- signin.html `-- signup.html `-- scripts/ |-- app.js |-- controllers.js `-- services.js
Angularアプリケーションのブートストラップ
spa.blade.php
アプリケーションの実行に必要な最低限の要素が含まれています。スタイリングにはTwitterBootstrapを使用し、 ブーツウォッチ 。 AJAX呼び出しを行うときに視覚的なフィードバックを得るには、 角度ローディングバー XHRリクエストをインターセプトし、ローディングバーを作成するスクリプト。ヘッダーセクションには、次のスタイルシートがあります。
ngStorage
マークアップのフッターには、ライブラリへの参照と、Angularモジュール、コントローラー、サービスのカスタムスクリプトが含まれています。
Authorization
使用しています token
AngularJSのライブラリ。トークンをブラウザのローカルストレージに保存し、 Toggle navigation JWT Angular example
を介してリクエストごとにトークンを送信できるようにします。ヘッダ。
もちろん、実稼働環境では、パフォーマンスを向上させるために、すべてのスクリプトファイルとスタイルシートを縮小して結合します。
Bootstrapを使用してナビゲーションバーを作成しました。これにより、ユーザーのサインインステータスに応じて、適切なリンクの表示が変更されます。サインインステータスは、app.js
の存在によって決定されます。コントローラのスコープ内の変数。
angular.module('app', [ 'ngStorage', 'ngRoute', 'angular-loading-bar' ]) .constant('urls', { BASE: 'http://jwt.dev:8000', BASE_API: 'http://api.jwt.dev:8000/v1' }) .config(['$routeProvider', '$httpProvider', function ($routeProvider, $httpProvider) { $routeProvider. when('/', { templateUrl: 'partials/home.html', controller: 'HomeController' }). when('/signin', { templateUrl: 'partials/signin.html', controller: 'HomeController' }). when('/signup', { templateUrl: 'partials/signup.html', controller: 'HomeController' }). when('/restricted', { templateUrl: 'partials/restricted.html', controller: 'RestrictedController' }). otherwise({ redirectTo: '/' });
ルーティング
HomeController
という名前のファイルがありますこれは、すべてのフロントエンドルートの構成を担当します。
RestrictedController
ここで、Authorization
のいずれかによって処理される4つのルートを定義したことがわかります。または$httpProvider.interceptors.push(['$q', '$location', '$localStorage', function ($q, $location, $localStorage) { return { 'request': function (config) { config.headers = config.headers || {}; if ($localStorage.token) { config.headers.Authorization = 'Bearer ' + $localStorage.token; } return config; }, 'responseError': function (response) { if (response.status === 401 || response.status === 403) { $location.path('/signin'); } return $q.reject(response); } }; }]);
。すべてのルートは部分的なHTMLビューに対応します。また、バックエンドへのHTTPリクエストのURLを含む2つの定数を定義しました。
インターセプターをリクエストする
AngularJSの$ httpサービスを使用すると、バックエンドと通信してHTTPリクエストを行うことができます。この場合、すべてのHTTPリクエストをインターセプトし、controllers.js
を挿入します。ユーザーが認証されている場合は、JWTを含むヘッダー。インターセプターを使用して、グローバルHTTPエラーハンドラーを作成することもできます。これは、ブラウザのローカルストレージで利用可能な場合にトークンを挿入するインターセプターの例です。
HomeController
コントローラー
RestrictedController
でファイル、アプリケーション用に2つのコントローラーを定義しました:HomeController
およびAuth
。 angular.module('app') .controller('HomeController', ['$rootScope', '$scope', '$location', '$localStorage', 'Auth', function ($rootScope, $scope, $location, $localStorage, Auth) { function successAuth(res) { $localStorage.token = res.token; window.location = '/'; } $scope.signin = function () { var formData = { email: $scope.email, password: $scope.password }; Auth.signin(formData, successAuth, function () { $rootScope.error = 'Invalid credentials.'; }) }; $scope.signup = function () { var formData = { email: $scope.email, password: $scope.password }; Auth.signup(formData, successAuth, function () { $rootScope.error = 'Failed to signup'; }) }; $scope.logout = function () { Auth.logout(function () { window.location = '/' }); }; $scope.token = $localStorage.token; $scope.tokenClaims = Auth.getTokenClaims(); }])
サインイン、サインアップ、およびログアウト機能を処理します。サインインフォームとサインアップフォームからRestrictedController
にユーザー名とパスワードのデータを渡します。 HTTPリクエストをバックエンドに送信するサービス。次に、バックエンドからの応答に応じて、トークンをローカルストレージに保存するか、エラーメッセージを表示します。
getRestrictedData
getApiData
同じように動作しますが、Data
を使用してデータをフェッチするだけです。および .controller('RestrictedController', ['$rootScope', '$scope', 'Data', function ($rootScope, $scope, Data) { Data.getRestrictedData(function (res) { $scope.data = res.data; }, function () { $rootScope.error = 'Failed to fetch restricted content.'; }); Data.getApiData(function (res) { $scope.api = res.data; }, function () { $rootScope.error = 'Failed to fetch restricted API content.'; }); }]);
Authorization
の関数サービス。
tokenClaims
バックエンドは、ユーザーが認証されている場合にのみ、制限されたデータを提供する責任があります。つまり、制限されたデータで応答するには、そのデータのリクエストに、getTokenClaims
内に有効なJWTが含まれている必要があります。ヘッダーまたはクエリ文字列。そうでない場合、サーバーは401Unauthorizedエラーステータスコードで応答します。
認証サービス
Authサービスは、バックエンドへのサインインとHTTPリクエストのサインアップを担当します。リクエストが成功した場合、レスポンスには署名されたトークンが含まれ、その後base64でデコードされ、同封のトークンクレーム情報がangular.module('app') .factory('Auth', ['$http', '$localStorage', 'urls', function ($http, $localStorage, urls) { function urlBase64Decode(str) { var output = str.replace('-', '+').replace('_', '/'); switch (output.length % 4) { case 0: break; case 2: output += '=='; break; case 3: output += '='; break; default: throw 'Illegal base64url string!'; } return window.atob(output); } function getClaimsFromToken() { var token = $localStorage.token; var user = {}; if (typeof token !== 'undefined') { var encoded = token.split('.')[1]; user = JSON.parse(urlBase64Decode(encoded)); } return user; } var tokenClaims = getClaimsFromToken(); return { signup: function (data, success, error) { $http.post(urls.BASE + '/signup', data).success(success).error(error) }, signin: function (data, success, error) { $http.post(urls.BASE + '/signin', data).success(success).error(error) }, logout: function (success) { tokenClaims = {}; delete $localStorage.token; success(); }, getTokenClaims: function () { return tokenClaims; } }; } ]);
に保存されます。変数。これはangular.module('app') .factory('Data', ['$http', 'urls', function ($http, urls) { return { getRestrictedData: function (success, error) { $http.get(urls.BASE + '/restricted').success(success).error(error) }, getApiData: function (success, error) { $http.get(urls.BASE_API + '/restricted').success(success).error(error) } }; } ]);
を介してコントローラーに渡されます関数。
|_+_|
データサービス
これは、認証サーバーとAPIサーバーにダミーの制限付きデータを要求する単純なサービスです。リクエストを行い、成功とエラーのコールバックをコントローラーに委任します。
|_+_|
トークンベースの認証により、特定の認証スキームに関連付けられていない分離されたシステムを構築できます。トークンはどこでも生成され、トークンの署名に同じ秘密鍵を使用するシステムで消費される可能性があります。モバイル対応であり、Cookieを使用する必要はありません。
JSON Web Tokenは、一般的なすべてのプログラミング言語で機能し、急速に人気が高まっています。 Google、Microsoft、Zendeskなどの企業が支援しています。インターネット技術特別調査委員会(IETF)による標準仕様は次のとおりです。 まだドラフト版です 将来的には少し変更される可能性があります。
JWTについては、処理方法など、まだカバーすべきことがたくさんあります。 セキュリティ 詳細、および有効期限が切れたときにトークンを更新しますが、JSON Web Tokenチュートリアルでは、基本的な使用法と、さらに重要なことに、JWTを使用する利点を示す必要があります。
これは、Authorizationと呼ばれるHTTPヘッダーを介して文字列形式「Bearer $ your_token_here」で渡されるJWTを参照します。
JWTは、JSON Web Tokenの略で、最新のWebアプリで使用される一般的な認証戦術です。
JSONは、JavaScriptで許可されているデータリテラル形式によく似たデータ形式です。これは、ネストされたオブジェクトと配列、および文字列と数値のリテラルを許可する階層形式です。