خبر و ترفند روز

خبر و ترفند های روز را اینجا بخوانید!

نحوه تنظیم احراز هویت پاسپورت در برنامه Node و Postgres

شروع به استفاده از Passport.js برای احراز هویت برنامه وب گره خود با حداقل سر و صدا کنید.

به عنوان یک توسعه دهنده، این مسئولیت شماست که از اطلاعات کاربران خود از طریق احراز هویت محافظت کنید. می توانید از Passport.js برای احراز هویت کاربران در برنامه Node و Postgres استفاده کنید.

با ایجاد یک سرور Node با نقاط پایانی برای ثبت نام، ورود به سیستم و خروج کاربران شروع کنید. می‌توانید به پاسپورت اجازه دهید تا احراز هویت را کنترل کند تا دسترسی غیرمجاز به برنامه شما را محدود کند.

ایجاد جدول کاربران

برای احراز هویت کاربر، از ایمیل و رمز عبور استفاده خواهید کرد. این بدان معناست که جدول کاربران باید حاوی یک ایمیل و یک فیلد رمز عبور باشد. در خط فرمان psql، یک پایگاه داده جدید به نام nodeapp ایجاد کنید:

CREATE DATABASE nodeapp;

سپس یک جدول برای ذخیره کاربران ایجاد کنید:

CREATE TABLE users (
 id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
 email CHAR(128),
 password CHAR(60)
);

این کد یک جدول جدید حاوی ایمیل، رمز عبور و یک فیلد شناسه تولید خودکار ایجاد می کند.

ایجاد Node Server

Node.js یک محیط اجرای جاوا اسکریپت سمت سرور است که به ما امکان می دهد سرورهای HTTP را به سرعت ایجاد کنیم. برای ساده‌سازی فرآیند ایجاد سرور و مسیرهای مختلف HTTP، می‌توانید از Express، یک چارچوب وب Node.js استفاده کنید.

این دستور را برای ایجاد یک پوشه جدید به نام postgres-auth اجرا کنید:

mkdir postgres-auth

سپس npm را مقداردهی اولیه کنید:

npm init -y

در نهایت Express را نصب کنید:

npm install express

اکنون می توانید وب سرور Node را ایجاد کنید.

در یک فایل جدید به نام index.js موارد زیر را اضافه کنید:

const express = require("express");
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.listen(3000, () => console.log("Listening on port 3000"));

اجرای این کد سرور را راه اندازی می کند و موارد زیر را در کنسول ثبت می کند:

Listening on port 3000

اتصال به PostgreSQL

برای اتصال به PostgreSQL از node-postgres استفاده کنید. node-postgres یک درایور اتصال است که یک رابط بین Node و Postgres فراهم می کند.

برای نصب node-postrges از طریق npm موارد زیر را اجرا کنید:

npm install pg

هنگامی که آن کتابخانه را نصب کردید، یک فایل جدید به نام db.js ایجاد کنید و آن را به پایگاه داده متصل کنید:

const { Client } = require("pg");
const { user, host, database, password, port } = require("./dbConfig");
 
const client = new Client({
  user,
  host,
  database,
  password,
  port,
});
 
client.connect();

module.exports = client;

متد کلاینت از node-postgres جزئیات پایگاه داده ای را که به آن متصل می شوید، می گیرد. این برنامه جزئیات اتصال خود را از فایلی به نام dbConfig وارد می کند. بنابراین، آن فایل را ایجاد کنید و کد زیر را به آن اضافه کنید:

module.exports = {
  user: "postgres",
  host: "localhost",
  database: "nodeapp",
  password: "yourPassword",
  port: 5432,
};

ایجاد توابع کمکی پایگاه داده

استفاده از توابع جداگانه برای تعامل با پایگاه داده همیشه تمرین خوبی است. آنها نوشتن تست های واحد را آسان می کنند و قابلیت استفاده مجدد را بهبود می بخشند. برای نقطه پایانی ثبت نام، باید دو تابع ایجاد کنید:

  1. برای بررسی اینکه آیا ایمیل قبلا ثبت شده است یا خیر.
  2. برای ایجاد کاربر.
مطلب مرتبط:   با GitHub Actions یک React Application را در Firebase اجرا کنید

هدف فقط ثبت نام کاربر در صورتی است که در پایگاه داده وجود نداشته باشد.

یک فایل جدید به نام helper.js ایجاد کنید و سرویس گیرنده پایگاه داده را از db.js وارد کنید:

const client = require("./db.js")

سپس یک تابع جدید به نام emailExists():

const emailExists = async (email) => {
  const data = await client.query("SELECT * FROM users WHERE email=$1", [
    email,
  ]);
 
  if (data.rowCount == 0) return false;
  return data.rows[0];
};

این تابع یک ایمیل دریافت می کند و بررسی می کند که آیا از قبل در حال استفاده است یا خیر. این کار را با استفاده از عبارت SELECT انجام می دهد که ردیفی را برمی گرداند که دارای یک فیلد ایمیل است که با مقدار ارائه شده توسط کاربر ثبت نام مطابقت دارد. اگر ایمیل وجود نداشته باشد، false برمی گردد.

برای ایجاد تابعی که کاربر را ایجاد می کند، تابعی به نام ()createUser را به helper.js اضافه کنید:

const createUser = async (email, password) => {
  const salt = await bcrypt.genSalt(10);
  const hash = await bcrypt.hash(password, salt);
 
  const data = await client.query(
    "INSERT INTO users(email, password) VALUES ($1, $2) RETURNING id, email, password",
    [email, hash]
  );
 
  if (data.rowCount == 0) return false;
  return data.rows[0];
};

این تابع مقادیر ایمیل و رمز عبور را می گیرد. از عبارت INSERT برای ایجاد یک ردیف جدید با این جزئیات استفاده می کند و در صورت موفقیت، کاربر تازه ایجاد شده را برمی گرداند. توجه داشته باشید که قبل از ذخیره رمز عبور، باید آن را با استفاده از bcrypt هش کنید. ذخیره رمزهای عبور به صورت متن ساده هرگز ایده خوبی نیست. اگر هکرها به پایگاه داده کاربران شما دسترسی داشته باشند، می توانند به راحتی به اطلاعات حساس دسترسی پیدا کنند.

برای شروع استفاده از bcryptjs را نصب کنید:

npm install bcryptjs

در helper.js، bcryptjs را وارد کنید:

const bcrypt = require("bcryptjs")

با استفاده از Bcryptjs، پایگاه داده تنها رمز عبور رمزگذاری شده را ذخیره می کند. بنابراین، در هنگام ورود، باید رمز عبور متن ساده داده شده توسط کاربر و رمز عبور هش شده در پایگاه داده را با هم مقایسه کنید. برای این کار می توانید از روش مقایسه ارائه شده توسط Bcryptjs استفاده کنید.

مطلب مرتبط:   10 شغل و شغل برنامه نویسی کامپیوتر که تقاضای بالایی دارند

یک تابع به نام matchPassword():

const matchPassword = async (password, hashPassword) => {
  const match = await bcrypt.compare(password, hashPassword);
  return match
};

رمز عبور ساده و هش را دریافت می کند و سپس از ()Bcrypt.compare برای تعیین اینکه آیا رمز عبور ارائه شده صحیح است یا خیر استفاده می کند. اگر باشد، true را در غیر این صورت، false را برمی گرداند.

اینها همه توابعی هستند که ما برای تعامل با پایگاه داده استفاده خواهیم کرد. مطمئن شوید که همه آنها را در پایان صادر کنید:

module.exports = { emailExists, createUser, matchPassword };

پیکربندی پاسپورت

Passport یک میان افزار احراز هویت Node است که بیش از 500 استراتژی احراز هویت مانند ورود به سیستم اجتماعی، توکن های وب JSON (JWT) و احراز هویت ایمیل را ارائه می دهد. ما از دومی استفاده خواهیم کرد که استراتژی پاسپورت-محلی ارائه می کند.

برای نصب passport و passport-local از دستور زیر استفاده کنید:

npm install passport
npm install passport-local

در مرحله بعد، پاسپورت را برای ورود کاربران فعلی و ثبت نام کاربران جدید پیکربندی کنید.

با ایجاد یک فایل جدید passportConfig.js شروع کنید. سپس، استراتژی محلی پاسپورت و توابع کمکی پایگاه داده را که ایجاد کردید وارد کنید:

const LocalStrategy = require("passport-local");
const { emailExists, createUser, matchPassword } = require("./helper");

در همان فایل موارد زیر را برای تنظیم ثبت نام کاربر اضافه کنید:

module.exports = (passport) => {
  passport.use(
    "local-signup",
    new LocalStrategy(
      {
        usernameField: "email",
        passwordField: "password",
      },
      async (email, password, done) => {
        try {
          const userExists = await emailExists(email)
 
          if (userExists) {
            return done(null, false);
          }
 
          const user = await createUser(email, password);
          return done(null, user);
        } catch (error) {
          done(error);
        }
      }
    )
  );
}

از آنجایی که passport-local انتظار نام کاربری و رمز عبور دارد و شما از ایمیل استفاده می کنید، قسمت نام کاربری را روی یک ایمیل تنظیم کنید. کاربر یا بهتر است بگوییم قسمت frontend این برنامه ایمیل و رمز عبور را در بدنه درخواست ارسال می کند. با این حال، نیازی نیست خودتان مقادیر را استخراج کنید زیرا Passport آن را در پس‌زمینه مدیریت می‌کند.

این برنامه ابتدا بررسی می کند که آیا ایمیل قبلاً با استفاده از تابع emailExists () از helper.js گرفته شده است یا خیر. اگر ایمیل در پایگاه داده وجود نداشته باشد، یک کاربر جدید با تابع ()createUser ایجاد می کند. در نهایت، شی کاربر را برمی گرداند.

مطلب مرتبط:   نحوه هش و تأیید یک رمز عبور در Node.js با bcrypt

برای ورود کاربران، موارد زیر را به passportConfig.js اضافه کنید:

module.exports = (passport) => {
  passport.use(
    "local-signup",
    new LocalStrategy(
// sign up
    )
  );
  passport.use(
    "local-login",
    new LocalStrategy(
      {
        usernameField: "email",
        passwordField: "password",
      },
      async (email, password, done) => {
        try {
          const user = await emailExists(email);
          if (!user) return done(null, false);
          const isMatch = await matchPassword(password, user.password);
          if (!isMatch) return done(null, false);
          return done(null, {id: user.id, email: user.email});
        } catch (error) {
          return done(error, false);
        }
      }
    )
  );
};

در اینجا، برنامه ابتدا بررسی می کند که آیا ایمیل ثبت شده است یا خیر. اگر نه، false برمی گردد. اگر ایمیل را پیدا کند، رمز عبور خود را با رمز درخواست مقایسه می کند. اگر پسوردها مطابقت داشته باشند، کاربر را وارد کرده و شی کاربر را برمی گرداند.

مرحله آخر ایجاد نقاط پایانی API است:

  • POST /auth/signup
  • POST /auth/login

هر دوی این نقاط پایانی یک ایمیل و رمز عبور در بدنه درخواست دریافت خواهند کرد. آنها همچنین شامل توابع میان‌افزار احراز هویت پاسپورت می‌شوند که ما اخیراً پیکربندی کردیم.

Passport را در یک فایل جدید به نام server.js وارد و تنظیم کنید:

const passport = require("passport");
require("./passportConfig")(passport);

سپس مسیرهای زیر را اضافه کنید:

app.post(
  "/auth/signup",
  passport.authenticate("local-signup", { session: false }),
  (req, res, next) => {
    res.json({
      user: req.user,
    });
  }
);

app.post(
  "/auth/login",
  passport.authenticate("local-login", { session: false }),
  (req, res, next) => {
    res.json({ user: req.user });
  }
);

هر دوی این مسیرها در صورت موفقیت یک شی JSON حاوی کاربر را برمی گرداند.

API خود را با استفاده از تست های واحد بررسی کنید

می توانید از Passport برای احراز هویت یک برنامه Node با استفاده از یک برنامه PostgreSQL استفاده کنید. شما نقاط پایانی API را برای ثبت نام و ورود کاربران ایجاد کرده اید.

در حالی که می‌توانید از کلاینت‌های REST مانند Postman برای تست عملکرد یک API استفاده کنید، نوشتن تست‌های واحد بسیار ساده‌تر است. تست های واحد به شما این امکان را می دهد که بخش های جداگانه برنامه خود را آزمایش کنید. به این ترتیب، حتی اگر یک نقطه پایانی شکست بخورد، می‌توانید نقطه دقیق شکست را مشخص کنید. یکی از ابزارهایی که می توانید برای تست برنامه های Node استفاده کنید، Jest است.