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のip netnsコマンドを使用してネットワークポートを分離し、IPアドレスを設定します。

1. 分離マーカーを追加します。 ip netns add fd 2. 指定されたネットワーク カ...

Vue で lodop 印刷コントロールを使用してブラウザ互換の印刷を実現する方法

序文このコントロールを直接印刷すると下部に透かしが入りますが、公式 Web サイトから購入することで...

VueはExcelデータをエクスポートするパブリック関数メソッドをカプセル化します

vue+element UI は Excel データをエクスポートするためのパブリック関数をカプセル...

Windows Server 2016 リモート デスクトップ サービスの構成とライセンスのアクティブ化 (2 ユーザー)

Server 2016 のリモート デスクトップ接続のデフォルト数は 2 ユーザーです。2 人以上...

Linux リモート管理と sshd サービス検証の知識ポイントの詳細な説明

1. SSHリモート管理SSH の定義SSH (Secure Shell) は、主にキャラクタ イン...

CSS スタッキングと Z インデックスのサンプルコード

カスケードとカスケードレベルHTML 要素は 3 次元の概念です。水平方向と垂直方向に加えて、「Z ...

Windows 10 64 ビット版に MySQL 5.6.35 をインストールするためのグラフィック チュートリアル

1. MySQL Community Server 5.6.35をダウンロードするダウンロードアドレ...

Google ブラウザのラベルと入力間のスペースに関する小さな問題

最初にコード、次にテキストコードをコピーコードは次のとおりです。 <!DOCTYPE html...

ウェブデザインの教育または学習プログラム

セクションコース内容営業時間1 ウェブデザインの概要2 2 HTML 基本タグとフォーマットタグ 2...

数千万のデータを扱うMySQLのページングクエリのパフォーマンスを最適化する

MySQL のデータ量が多い場合、制限ページングが使用されます。ページ数が増えると、クエリの効率が低...

vue 動的コンポーネント

目次1. コンポーネント2. キープアライブ2.1 問題点2.2 キープアライブを使って解決する2....

NextCloud プライベート クラウド ストレージ ネットワーク ディスクの構築に関する詳細なチュートリアル

Nextcloud は、オープンソースで無料のプライベート クラウド ストレージ ネットワーク ディ...

MySQLの文字セットと検証ルールの詳細な説明

1いくつかの一般的な文字セットMySQL で最も一般的な文字セットには、ASCII 文字セット、ラテ...

Node.jsはブレークポイント再開を実装する

目次ソリューション分析スライス履歴書のダウンロード具体的な解決プロセス論理的分析フロントエンドサーバ...