ホームページ >ウェブフロントエンド >jsチュートリアル >Node.js で安全な認証をマスターする: bcrypt.js と JWT を使用したログイン/ログアウト

Node.js で安全な認証をマスターする: bcrypt.js と JWT を使用したログイン/ログアウト

Susan Sarandon
Susan Sarandonオリジナル
2025-01-11 14:34:43576ブラウズ

これから起動する Web アプリケーションを構築していると想像してください。ユーザー インターフェイスを慎重に設計し、エキサイティングな機能を追加し、すべてがスムーズに動作するようにしました。しかし、発売日が近づくにつれて、セキュリティというしつこい懸念が気になり始めます。具体的には、適切なユーザーのみがアプリケーションの適切な部分にアクセスできるようにする方法です。ここで認証が登場します。

認証はユーザーが誰であるかを確認するプロセスであり、Web 開発の重要な側面です。広大なデジタル環境では、ユーザーがアプリケーションに安全にログインおよびログアウトできることを保証することが最も重要です。一歩間違えるとアプリが攻撃に対して脆弱になり、ユーザーデータが危険にさらされる可能性があります。

導入

この記事では、bcrypt.js を使用してパスワードをハッシュし、JWT トークンを使用してユーザー セッションを管理する、Node.js での安全な認証について説明します。最後には、強力なログイン/ログアウト システムを実装し、ユーザーのデータを安全に保つ方法をしっかりと理解できるようになります。

それでは、環境のセットアップから JWT によるルートの保護まで、完全な認証システムを構築する旅に着手しましょう。 Node.js アプリをロックダウンする準備はできていますか?始めましょう。

Node.js プロジェクト環境のセットアップ

まず、npm init -y を使用して Node.js プロジェクトを初期化し、デフォルト設定で package.json ファイルを作成します。次に、必須パッケージをインストールします。サーバーをセットアップするための Express、MongoDB を管理するための mongoose、JWT トークンを処理するための jsonwebtoken、パスワードをハッシュするための bcryptjs、環境変数のための dotenv、クロスオリジン リソース共有を有効にするための cors、Cookie を解析するための cookie-parser。最後に、コード変更時にサーバーを自動的に再起動するために、nodemon を開発依存関係として追加します。

1.`npm init -y`
2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser`
3.`npm install nodemon -D`

次に、package.json ファイルを変更します。私のコードのようなスクリプトを追加して入力します。

"scripts": {
    "dev": "nodemon backend/index.js",
    "start": "node backend/index.js"
  },
"type": "module",

基本的なサーバーのセットアップ

次に、基本的な Express サーバーをセットアップします。 Index.js という名前のファイルを作成します。このコードは Express を初期化し、アプリケーションのインスタンスを作成します。次に、受信した HTTP GET リクエストを処理するためのルート URL (「/」) のルートを定義します。その後、ポート 8000 でサーバーを起動し、受信リクエストをリッスンできるようにします。

import express from "express";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

基本認証ルートの設定

次に、「routes」という名前のフォルダーを作成し、そのフォルダー内に authRoute.js という名前の新しいファイルを作成し、以下のコードを貼り付けてルートの基本を確認します。

このコード スニペットでは、Express を使用してさまざまな認証エンドポイントのルートを設定しています。まず、Express ライブラリをインポートし、新しいルーター インスタンスを作成します。次に、/signup、/login、/logout の 3 つの GET ルートを定義します。各ルートは、それぞれのエンドポイントがヒットしたことを示す JSON オブジェクトで応答します。最後に、ルーター インスタンスをデフォルトのエクスポートとしてエクスポートし、アプリケーションの他の部分で使用できるようにします。

1.`npm init -y`
2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser`
3.`npm install nodemon -D`

次に、エンドポイントをテストするための認証ルートを追加して、index.js を変更します。

"scripts": {
    "dev": "nodemon backend/index.js",
    "start": "node backend/index.js"
  },
"type": "module",

これで、ブラウザでテストできます...ただし、便宜上 Postman を使用します。このようにしてすべてのエンドポイントをテストできます。

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

同様に、ログアウトサインアップなどの他のルートも表示されます。

これで、基本アプリの準備が整いました。これを堅牢で適切な認証システムにしましょう。

Mongoose スキーマを使用したユーザー モデルの作成

さて、まず mongoDB データベースを準備します。これを行うには、Model フォルダーを作成し、その下に User.js ファイルを作成し、このファイルに mongoDB データベース内のユーザーの Mongoose スキーマとモデルを追加します。スキーマには、ユーザー名、フルネーム、パスワード、電子メールのフィールドが含まれており、それぞれに指定されたデータ型と、一意性や必要なステータスなどの制約があります。パスワードフィールドの最小長も 6 文字です。

import express from "express";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

Mongoose を使用して MongoDB に接続する

それでは、データベースに接続してみましょう。 db という名前のフォルダーを作成し、その中に connectDB.js というファイルを作成します。このファイルでは、Mongoose を使用して MongoDB データベースへの接続を試行する非同期関数 connectMongoDB を定義します。 MONGO_URI 環境変数からデータベース接続文字列を取得します。接続が成功すると、ホスト名を含む成功メッセージがログに記録されます。失敗した場合、エラーが記録され、ステータス コード 1 でプロセスが終了します。関数は、アプリケーションの他の部分で使用するためにエクスポートされます。

import express from "express";

// Create a new Express router instance
const router = express.Router();

// Define a GET route for the signup endpoint
router.get("/signup", (req, res) => {
  // Return a JSON response indicating that the signup endpoint was hit
  res.json({
    data: "You hit signup endpoint",
  });
});

// Define a GET route for the login endpoint
router.get("/login", (req, res) => {
  // Return a JSON response indicating that the login endpoint was hit
  res.json({
    data: "You hit login endpoint",
  });
});

// Define a GET route for the logout endpoint
router.get("/logout", (req, res) => {
  // Return a JSON response indicating that the logout endpoint was hit
  res.json({
    data: "You hit logout endpoint",
  });
});

// Export the router instance as the default export
export default router;

MONGO_URI を使用するには、.env ファイルで作成する必要があります。ここではローカルの mongoDB セットアップ接続文字列を使用しました。必要に応じて、mongoDB アトラスを使用することもできます。

import express from "express";
import authRoute from "./routes/authRoutes.js";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.use("/api/auth", authRoute);

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

サインアップ機能

次に、サインアップ関数を作成します。この最初の手順では、フォルダー コントローラーを作成し、そこに authController.js
ファイルを作成します。

import mongoose from "mongoose";

// Define the User schema with various fields and their data types
const userSchema = new mongoose.Schema(
  {
    // The unique username of the user
    username: {
      type: String,
      required: true,
      unique: true,
    },
    fullName: {
      type: String,
      required: true,
    },
    // The password of the user (min length: 6)
    password: {
      type: String,
      required: true,
      minLength: 6,
    },
    // The email of the user (unique)
    email: {
      type: String,
      required: true,
      unique: true,
    },
  },
  { timestamps: true }
);

// Create the User model based on the userSchema
const User = mongoose.model("User", userSchema);

// Export the User model
export default User;

まず、リクエスト本文から fullName、ユーザー名、電子メール、およびパスワードを抽出します。正規表現を使用して電子メール形式を検証し、形式が無効な場合は 400 ステータスを返します。

次に、関数はユーザー名または電子メールがデータベースにすでに存在するかどうかを確認します。どちらかを選択すると、エラー メッセージを含む 400 ステータスが返されます。また、パスワードが少なくとも 6 文字であることも保証され、この条件が満たされない場合は別の 400 ステータスが送信されます。

パスワードは bcrypt を使用して安全にハッシュされます。提供されたデータを使用して新しいユーザー インスタンスが作成され、データベースに保存されます。

保存後、関数は JWT トークンを生成し、それを Cookie として設定し、ユーザーの ID、フルネーム、ユーザー名、および電子メールを含む 201 ステータスを返します。エラーが発生した場合はログに記録され、「内部サーバー エラー」メッセージとともに 500 ステータスが送信されます。

この機能を有効にするには、これらをインポートする必要があります

1.`npm init -y`
2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser`
3.`npm install nodemon -D`

何か気づきましたか? generateTokenAndSetCookie という新しいもの...そのコードを見てみましょう...フォルダー utils を作成し、そこにgenerateTokenAndSetCookie.js.

"scripts": {
    "dev": "nodemon backend/index.js",
    "start": "node backend/index.js"
  },
"type": "module",

**generateTokenAndSetCookie **関数は JWT を作成し、それをユーザー認証用の Cookie に保存します。

JWT 生成:

この関数は、jsonwebtoken ライブラリを使用して JWT を作成します。ユーザーの ID と秘密鍵 (環境変数の JWT_SECRET) を使用してトークンに署名し、有効期限が 15 日になるように設定します。

Cookie の設定:

その後、トークンはユーザーのブラウザの Cookie に保存されます。 Cookie はいくつかのセキュリティ属性で構成されています:

  • maxAge: Cookie の有効期間を 15 日に設定します。
  • httpOnly: JavaScript 経由で Cookie にアクセスできないようにし、XSS (クロスサイト スクリプティング) 攻撃から保護します。
  • sameSite: "strict": 同じサイトからのリクエストでのみ送信される Cookie を制限することで、CSRF (クロスサイト リクエスト フォージェリ) 攻撃を防ぎます。
  • セキュア: 環境が開発環境でない場合に Cookie が HTTPS 経由でのみ送信されるようにし、セキュリティ層を追加します。

この機能により、ユーザーのセッションが安全かつ永続的であることが保証され、認証プロセスの重要な部分となります。

ここでは、.env に別の環境変数 JWT_SECRET を追加する必要があります。このように、数値と文字列を任意に組み合わせて追加できます。

import express from "express";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

これでサインアップ機能が完了しました。今すぐルートを作成してください。

import express from "express";

// Create a new Express router instance
const router = express.Router();

// Define a GET route for the signup endpoint
router.get("/signup", (req, res) => {
  // Return a JSON response indicating that the signup endpoint was hit
  res.json({
    data: "You hit signup endpoint",
  });
});

// Define a GET route for the login endpoint
router.get("/login", (req, res) => {
  // Return a JSON response indicating that the login endpoint was hit
  res.json({
    data: "You hit login endpoint",
  });
});

// Define a GET route for the logout endpoint
router.get("/logout", (req, res) => {
  // Return a JSON response indicating that the logout endpoint was hit
  res.json({
    data: "You hit logout endpoint",
  });
});

// Export the router instance as the default export
export default router;

それでは、index.js を変更しましょう。ここでは、新しいインポートをいくつか追加しました。 dotenv: .env から環境変数を安全にロードします。 express.json(): 受信した JSON リクエストを解析します。 express.urlencoded({ extend: true }): URL エンコードされたデータを解析します。 cookieParser: JWT トークンの Cookie を処理します。 connectMongoDB(): データ ストレージのために MongoDB に接続します。 ルート: /api/auth はサインアップ、ログイン、ログアウトを管理します。

これは、index.js の更新されたコードです

1.`npm init -y`
2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser`
3.`npm install nodemon -D`

それで。次に、Postman のサインアップ機能をテストします。うまくいくかどうか見てみましょう。

それで、結果は次のとおりです。

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

ここでは、正しく動作していることがわかり、mongoDB データベースも確認できます。

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

ログイン機能

次にログイン関数を作成します。もう一度 authController.js ファイルに戻りましょう

"scripts": {
    "dev": "nodemon backend/index.js",
    "start": "node backend/index.js"
  },
"type": "module",

ログイン コントローラーは、ユーザー名とパスワードを検証してユーザーを認証します。まず、ユーザー名を使用してデータベース内でユーザーを検索します。見つかった場合、提供されたパスワードと、bcrypt を使用してデータベースに保存されているハッシュ化されたパスワードが比較されます。ユーザー名またはパスワードが間違っている場合は、エラー応答が返されます。検証が成功すると、JWT トークンが生成され、generateTokenAndSetCookie を使用してそれを Cookie として設定し、ユーザーが正常にログインしたことを示す成功メッセージで応答します。

authRoutes.js にログイン ルートを追加しましょう

import express from "express";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

Postman でテストしてみましょう。

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT
ここでは、「ログイン済み」と正常に表示されていることがわかります。

ログアウト機能

わかりました。最後の関数、つまりログアウト関数です。これを実装してみましょう。とても簡単です。

import express from "express";

// Create a new Express router instance
const router = express.Router();

// Define a GET route for the signup endpoint
router.get("/signup", (req, res) => {
  // Return a JSON response indicating that the signup endpoint was hit
  res.json({
    data: "You hit signup endpoint",
  });
});

// Define a GET route for the login endpoint
router.get("/login", (req, res) => {
  // Return a JSON response indicating that the login endpoint was hit
  res.json({
    data: "You hit login endpoint",
  });
});

// Define a GET route for the logout endpoint
router.get("/logout", (req, res) => {
  // Return a JSON response indicating that the logout endpoint was hit
  res.json({
    data: "You hit logout endpoint",
  });
});

// Export the router instance as the default export
export default router;

ログアウト コントローラーは、res.cookie を使用してクライアントのブラウザーから JWT Cookie をクリアし、その値を空の文字列に設定し、maxAge を 0 に設定することでユーザーを安全にログアウトし、即時の有効期限を確保します。 Cookie のクリアが成功すると、ユーザーが正常にログアウトされたことを示すメッセージを含む成功応答が送信されます。このプロセス中にエラーが発生した場合、エラーを捕捉してログに記録し、内部サーバー エラー応答を返します。

このルートを authRoute.js に追加します

import express from "express";
import authRoute from "./routes/authRoutes.js";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.use("/api/auth", authRoute);

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

わかりました。最後の機能が正常に動作するかどうかをテストしてみましょう。

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

ああ!…非常にうまく機能しています。 ??

これで、この認証の完全なバックエンドの準備が整いました。 ??

私のnpmパッケージ

すべてを自分でコーディングしたくなく、迅速な解決策が必要な場合は、auth0_package という npm パッケージを作成しました。こちらから入手できます。

Githubリポジトリ

上記のコードはすべて、この github リポジトリから入手できます。

これでバックエンド アプリケーションが完成しました。次回のブログでは、これをフロントエンドと統合する方法について説明します。それでは、楽しみにしていてください??.

結論

結論として、Node.js アプリケーションに安全な認証を実装することは、ユーザー データを保護し、承認されたユーザーのみがアプリケーションの特定の部分にアクセスできるようにするために重要です。パスワードのハッシュ化に bcrypt.js を使用し、セッション管理に JWT トークンを使用することで、堅牢なログイン/ログアウト システムを作成できます。このアプローチにより、セキュリティが強化されるだけでなく、シームレスなユーザー エクスペリエンスも提供されます。 MongoDB データベースをセットアップし、ルーティングに Express を使用すると、バックエンド インフラストラクチャがさらに強化されます。これらのツールとテクニックを使用すると、Web アプリケーションが不正アクセスや潜在的なセキュリティ脅威から十分に保護されていることを確認して、自信を持って起動できます。

以上がNode.js で安全な認証をマスターする: bcrypt.js と JWT を使用したログイン/ログアウトの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。