Nodeはkoa2を使用してシンプルなJWT認証方式を実装します

Nodeはkoa2を使用してシンプルなJWT認証方式を実装します

JWT の紹介

JWTとは

正式名称はJSON Web Tokenで、現在最も人気のあるクロスドメイン認証ソリューションです。基本的な実装は、サーバーが認証した後、 JSONオブジェクトを生成し、それをユーザーに送り返すことです。ユーザーがサーバーと通信する場合、このJSONオブジェクトを送り返す必要があります。

JSON次のようになります。

{
 「名前」:「張三」、
 「役割」: 「管理者」、
 「有効期限」: 「2018年7月1日 00:00」
}

JWT が必要な理由は何ですか?

まず、 session_idCookie実装に基づいた一般的な認証プロセスを見てみましょう。

1. ユーザーはユーザー名とパスワードをサーバーに送信します。

2. サーバー検証に合格すると、ユーザーロール、ログイン時間などの関連データが現在のsessionに保存されます。

3. サーバーはユーザーにsession_idを返し、それをユーザーのCookieに書き込みます。

4. ユーザーによる後続の各リクエストでは、 session_idCookieを通じてサーバーに返されます。

5. サーバーはsession_idを受信し、以前に保存されたデータを検索して、ユーザーの ID を認識します。

しかし、ここで大きな問題があります。サーバー クラスターの場合、セッション データの共有が必要になり、各サーバーがセッションを読み取ることができます。この実装のコストは比較的高くなります。

JWT考え方を変え、 JSONデータをフロントエンドに返します。フロントエンドが再度リクエストすると、検証のためにデータがバックエンドに送信されます。つまり、サーバーはステートレスなので、拡張が容易になります。

JWT データ構造

JWTの 3 つの部分は次のとおりです。

Header 、次のようなもの

{
 "アルゴリズム": "HS256",
 "タイプ": "JWT"
}

alg属性は署名アルゴリズム ( algorithm ) を示し、デフォルトはHMAC SHA256 ( HS256と表記) です。 typ属性はtokentype JWT示します。JWT トークンはJWT

Payload 。これはJSONでもあり、送信する必要がある実際のデータを保存するために使用されます。 JWT 7 つの公式フィールドを指定します。下記の通り

  • iss (発行者): 発行者
  • exp (有効期限): 有効期限
  • sub (件名): 主題
  • aud (観客): 観客
  • nbf (Not Before): 有効時間
  • iat (発行日時): 発行時刻
  • jti (JWT ID): ID

もちろん、プライベートフィールドをカスタマイズすることもできます。 ただし、JWT はデフォルトでは暗号化されておらず、誰でも読み取ることができるため、この部分には秘密情報を入れないでください。

SignatureSignature部分は、データの改ざんを防ぐための最初の 2 つの部分の署名です。まず、 secret )を指定する必要があります。このキーはサーバーのみが知っており、ユーザーには公開できません。次に、 Headerで指定された署名アルゴリズム(デフォルトはHMAC SHA256 )を使用して、次の式に従って署名を生成します。

HMACSHA256
 base64UrlEncode(ヘッダー) + "." +
 base64UrlEncode(ペイロード)、
 秘密)

署名を計算した後、 HeaderPayloadSignatureの 3 つの部分が文字列に結合され、各部分が「ドット」(.) で区切られて、ユーザーに返されます。下記の通り

JWTのセキュリティ

  • JWTデフォルトでは暗号化されませんが、暗号化することは可能です。秘密データはJWTなしではJWTに書き込めません
  • JWT自体には認証情報が含まれており、漏洩すると誰でもトークンのすべての権限を取得できるようになります。盗難を減らすには、 JWTの有効期間を短く設定する必要があります。いくつかの重要な権限については、使用時にユーザーを再度認証する必要があります。
  • 盗難を減らすために、 JWT HTTPプロトコルを使用してプレーンテキストで送信するのではなく、 HTTPSプロトコルを使用して送信する必要があります。

Node の簡単なデモ - Koa JWT の実装

理論的な知識について説明した後、 JWT実装する方法を見てみましょう。一般的なプロセスは次のとおりです。

まず、ユーザーがログインすると、サーバーはユーザー情報に基づいてtokenを生成し、クライアントに返します。フロントエンドは、次のリクエストでtokenをサーバーに渡します。サーバーはトークンが有効であることを確認した後、データを返します。無効な場合は401ステータスコードを返す

ここではNodeを使って実装します。使用する主なライブラリは次の2つです。

jsonwebtoken は、 tokenの生成、検証などを行うことができます。

Koa-jwtミドルウェアは、主にtoken検証に使用されるjsonwebtokenさらにカプセル化します。

koaプロジェクトを素早く構築する

現時点では、 Vue-cliのようにkoaプロジェクトをすばやくビルドする公式の方法は存在しないことがわかりました。 ( koaプロジェクトの構築コストも低いのかもしれません)。しかし私は怠け者なので、比較的使いやすいツール、koa-generatorを見つけました。

インストール

npm をインストール -g koa-generator

koa2 my-project my-projectという新しいkoa2プロジェクトを作成します。

cd my-projectnpm install

プロジェクトを開始するnpm start

localhost:3000開く

トークンを生成する

デモンストレーションの便宜上、実際にはデータベースに保存されるユーザー情報を格納するための変数userList直接定義します。

const crypto = require("crypto"),
 jwt = require("jsonwebtoken");
// TODO: データベースを使用する // これはデータベースに保存する必要がありますが、これはデモンストレーション用です let userList = [];

クラスUserController {
 // ユーザーログイン static async login(ctx) {
  const データ = ctx.request.body;
  if (!data.name || !data.password) {
   ctx.body = {を返します
    コード: "000002", 
    メッセージ: 「無効なパラメータ」
   }
  }
  const result = userList.find(item => item.name === data.name && item.password === crypto.createHash('md5').update(data.password).digest('hex'))
  if (結果) {
   const トークン = jwt.sign(
    {
     名前: 結果.名前
    },
    "Gopal_token", // シークレット
    { expiresIn: 60 * 60 } // 60 * 60 秒
   );
   ctx.body = {を返します
    コード: "0",
    メッセージ: 「ログイン成功」、
    データ: {
     トークン
    }
   };
  } それ以外 {
   ctx.body = {を返します
    コード: "000002",
    メッセージ: 「ユーザー名またはパスワードが正しくありません」
   };
  }
 }
}

モジュールをエクスポートします。

jsonwebtokensignメソッドを使用してtokenを生成します。このメソッドの最初のパラメータはPayloadを参照します。これは、エンコード後にtokenに格納されるデータです。また、 tokenを検証した後に取得できるデータでもあります。 2 つ目は、サーバー固有の秘密鍵です。検証中にデコードするには、これらが同じである必要があり、秘密に保持されることに注意してください。一般的に、パブリック変数を定義するのが最適です。ここでは、デモンストレーションの便宜上、直接ハードコードされています。 3番目のパラメータはoptionで、 token有効期限を定義できます。

クライアントがトークンを取得する

フロントエンドがログインしてtokenを取得した後、それをcookieまたはlocalStorageに保存できます。ここではlocalStorageに直接保存します

ログイン() {
 これ.$axios
  .post("/api/ログイン", {
   ...このルールフォーム、
  })
  .then(res => {
   (res.code === "0"の場合){
    this.$message.success('ログインに成功しました');
    localStorage.setItem("トークン", res.data.token);
    this.$router.push("/");
   } それ以外 {
    this.$message(res.message);
   }
  });
}

axiosインターセプターをカプセル化し、リクエストが行われるたびに、リクエスト ヘッダーで検証のためにtokenサーバーに送信します。事前にCookieに配置しておけば自動的に送信できますが、クロスドメインにはできません。したがって、推奨される方法は、HTTP リクエスト ヘッダーAuthorizationに配置することです。ここでのAuthorization設定に注意し、先頭にBearerを追加します。詳細については、ベアラー認証を参照してください。

// axios リクエストインターセプターはリクエストデータを処理します axios.interceptors.request.use(config => {
 const トークン = localStorage.getItem('トークン');
 config.headers.common['Authorization'] = 'Bearer ' + token; // ここで Authorization に注意してください
 設定を返します。
})

トークンを確認する

検証にkoa-jwtミドルウェアを使用するのは、以下に示すように比較的簡単です。

// エラー処理 app.use((ctx, next) => {
 戻り値 next().catch((err) => {
   (エラーステータス === 401)の場合{
     ctx.ステータス = 401;
    ctx.body = '保護されたリソース。アクセスするには Authorization ヘッダーを使用します\n';
   }それ以外{
     エラーをスローします。
   }
 })
})

// 注: ルートの前に配置します app.use(koajwt({
 シークレット: 'Gopal_token'
}).unless({ // ホワイトリストのパスを設定する: [/\/api\/register/, /\/api\/login/]
}))

// ルート
app.use(index.routes(), index.allowedMethods())
app.use(users.routes()、users.allowedMethods()) を使用します

以下の点に注意することが重要です。

  • secret sign時と同じである必要があります
  • ログイン/登録など、検証する必要のないURLを指定するインターフェースのホワイトリストは、 unlessを通じて設定できます。
  • 検証ミドルウェアは、検証が必要なルートの前に配置する必要があります。 前述のURL検証できません。

デモ

ログインが必要なインターフェースに直接アクセスすると、 401が発生します。

最初に登録してからログインしてください。そうしないと、ユーザー名またはパスワードが間違っているというメッセージが表示されます。

ログイン後、 Authorizationを行うと正常にアクセスでき、 200返してデータを修正できます。

要約する

この記事では、 JWT認証に関する知識をまとめ、 koa2で実装した簡単なdemoを紹介します。皆様のお役に立てれば幸いです。

記事が長くなったので、比較的簡単なkoa-jwtのソースコードについて個別にお話しする機会がありました〜

この記事のdemoアドレス: クライアントとサーバー

参照する

JSON Web Token 入門チュートリアル

Node.js アプリケーション: Koa2 は認証に JWT を使用します

Node で koa2 を使用して簡単な JWT 認証方式を実装する方法についての記事はこれで終わりです。Node koa2 JWT 認証に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Node.js Koa2 が認証に JWT を使用する例

<<:  Trash-Cli: Linux のコマンドラインごみ箱ツール

>>:  Windows 10 での MySQL 5.7.17 のインストールと設定方法のグラフィック チュートリアル

推薦する

JS 日付コントロール My97DatePicker の基本的な使い方

My97DatePicker は非常に柔軟で使いやすい日付コントロールです。使い方はとても簡単です。...

DOCTYPE HTMLを使用する理由

これがないと、ブラウザはページをレンダリングするときに Quirks モードを使用することがわかって...

CentOS6.9 での MySQL 5.7.17 のインストールと設定のチュートリアル

CentOS6.9はMysql5.7をインストールします。参考までに、詳細は次のとおりです。 1. ...

Vueはechartsに基づいて3次元の縦棒グラフを実装します

3次元縦棒グラフは、正面、右側、上部の3つの部分で構成されています。描画するときは、正面をグラフィッ...

実行中の時計を実装するための純粋な CSS3 コード

操作効果コードの実装html <div id="ウォッチ"> <...

Nginx がフロントエンド リソースへのクロスドメイン アクセスの問題をどのように解決するかの詳細な説明

フロントエンドのクロスドメイン問題に2日間近く悩まされましたが、ようやくngnxを使って解決したので...

Linuxのアラーム機能の例の説明

Linuxアラーム機能の紹介上記のコード: #include <stdio.h> #in...

MySQL シリーズ 9 MySQL クエリ キャッシュとインデックス

目次チュートリアルシリーズ1. MySQL アーキテクチャクエリキャッシュキャッシュされないクエリ:...

Linux のメモリ管理とアドレス指定の詳細な紹介

目次1. コンセプトメモリ管理モード住所種別分類例: 2. ページ管理x86 アーキテクチャ 32 ...

Mysql5.7 で JSON 操作関数を使用する手順

序文JSON は、言語に依存しないテキスト形式を使用する軽量のデータ交換形式で、XML に似ています...

Linuxはiftopを使用してネットワークカードのトラフィックをリアルタイムで監視します

Linux は iftop を使用してネットワーク カードのトラフィックをリアルタイムで監視します。...

VMware15.5 インストール Ubuntu20.04 グラフィック チュートリアル

1. インストール前の準備1. 公式ウェブサイトからUbuntu 20.04のイメージファイルを直接...

テーブル関連の配置とJavascript操作テーブル、tr、td

適切に機能するテーブル プロパティ設定:コードをコピーコードは次のとおりです。 <テーブル セ...

Vue3 を使用して虫眼鏡効果を実現する方法の例

目次序文1. カプセル化の重要性2. どのようにカプセル化しますか? 1. 準備2. 梱包を開始する...

リストループスクロールを実現するための HTML+CSS+JavaScript サンプルコード

説明: 指定された時間内に前のノードのコンテンツを置き換えるタイマーを設定します。 1. キーコード...