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 のインストールと設定方法のグラフィック チュートリアル

推薦する

Linux xargsコマンドの使用

1. 機能: xargs は、stdin 内のスペースまたは改行で区切られたデータをスペースで区切ら...

Nodejs は JSON 文字列を JSON オブジェクトに変換するエラー解決法

JSON 文字列を JSON オブジェクトに変換するにはどうすればいいですか? JSON.parse...

JS 正規マッチングの落とし穴の記録

最近、JS の正規表現マッチングの落とし穴を発見したのですが、その時はあまりにも奇妙だったので、何か...

HTML Web ページ リスト タグ学習チュートリアル

HTML Web ページ リスト タグの学習チュートリアル。 HTML ページでは、リストはアウトラ...

JS はシンプルな todoList (メモ帳) 効果を実装します

メモ帳プログラムは、HTML + CSS + JavaScript の 3 つの主要なフロントエンド...

MySQL 5.7.24 のインストールと設定のグラフィックチュートリアル

この記事では、MySQL 5.7.24のインストールと設定のチュートリアルを参考までに紹介します。具...

Reactプロジェクトで要素を使用する方法

React プロジェクトで要素フレームワークを使用するのは今回が初めてです。非常に単純な問題に遭遇し...

JSはアニメーションのレイアウト変換を実装します

JS でアニメーションを記述する場合、移動前に相対位置を絶対位置に変換してからアニメーション機能を実...

Centos7 で keepalived ログを別のパスに設定する方法の詳細な説明

Keepalived のインストール: cd <keepalived_sourcecode_p...

反応自動構築ルーティングの実装

目次順序1. 集中ルーティング2. ファイルディレクトリ3. CompileRouterを作成する4...

Linux コマンドラインのワイルドカードとエスケープ文字の実装

ハードディスクのファイル属性のバッチ表示など、特定の種類のファイルに対してバッチ操作を実行する場合、...

Centos7 ベースの Nginx Web サイト サーバーの構築の詳細説明 (仮想 Web ホストの構成を含む)

1. Nginx サービス基盤Nginx (エンジン x) は、パフォーマンスの最適化のために特別...

Web デザイン TabIndex 要素

TabIndex は、Tab キーを押して、定義された TabIndex 要素を順番に取得し、各要素...

Vue で pdfjs を使用して PDF ファイルをプレビューする方法

目次序文考えるライブラリディレクトリの解析とダウンロード使い方ファイルの場所実際の通話質問要約する序...

jQueryとCSSを組み合わせてトップに戻る機能を実現

CSS操作 CS $("").css(名前|プロ|[,値|関数]) 位置$(&q...