Skill

TypeORM এর নিরাপত্তা best practices

টাইপওআরএম (TypeORM) - Web Development

373

TypeORM এবং নিরাপত্তা

TypeORM একটি জনপ্রিয় Object-Relational Mapping (ORM) লাইব্রেরি যা JavaScript এবং TypeScript অ্যাপ্লিকেশনগুলির জন্য ব্যবহৃত হয়। এটি ডেটাবেসের সাথে যোগাযোগের জন্য একটি সুবিধাজনক উপায় প্রদান করে, তবে যেহেতু TypeORM ডেটাবেসের সাথে সরাসরি যোগাযোগ করে, এর সঠিক ব্যবহার নিরাপত্তার দিক থেকে গুরুত্বপূর্ণ হয়ে ওঠে। TypeORM ব্যবহার করার সময় নিরাপত্তা বজায় রাখতে কিছু Best Practices অনুসরণ করা উচিত।

এখানে TypeORM ব্যবহারের সময় নিরাপত্তা নিশ্চিত করার জন্য কিছু গুরুত্বপূর্ণ টিপস এবং পদ্ধতির আলোচনা করা হলো:


১. SQL Injection থেকে সুরক্ষা

SQL Injection একটি সাধারণ নিরাপত্তা সমস্যা যা ডেটাবেসে অসুরক্ষিত SQL কুয়েরি পাঠানোর মাধ্যমে ঘটে। TypeORM এর ব্যবহারকারী ডেটা ইনপুটের উপর সরাসরি SQL কুয়েরি না পাঠিয়ে parameterized queries এবং prepared statements ব্যবহার করে SQL Injection থেকে সুরক্ষা পেতে পারেন।

Best Practice:

TypeORM স্বয়ংক্রিয়ভাবে prepared statements ব্যবহার করে, তাই আপনাকে SQL কুয়েরি লেখার সময় সরাসরি ডেটা সংযুক্ত করার প্রয়োজন হয় না। সবসময় query builder বা repository এর মতো নিরাপদ পদ্ধতিগুলি ব্যবহার করুন।

উদাহরণ:

import { getRepository } from "typeorm";
import { User } from "./entity/User";

// SQL Injection এড়ানোর জন্য, parameterized queries ব্যবহার করুন।
const userRepository = getRepository(User);
const users = await userRepository.find({
  where: { name: "John Doe" }
});

এখানে, find() মেথডটি নিরাপদ, কারণ এটি parameterized query ব্যবহার করে ডেটাবেসে সরাসরি ইউজারের ইনপুট ইনজেক্ট করে না।


২. Sensitive Data Encryption

আপনার অ্যাপ্লিকেশনে যদি কোনো sensitive data যেমন passwords, credit card numbers, বা api keys সংরক্ষিত থাকে, তবে সেগুলোকে encryption করে সংরক্ষণ করা অত্যন্ত গুরুত্বপূর্ণ। TypeORM ডেটাবেসে সোজা স্টোর করা ডেটাকে এনক্রিপ্ট করা এবং ডিক্রিপ্ট করা সহজ করে তোলে, কিন্তু নিরাপত্তার জন্য আপনাকে নিজে hashing বা encryption পদ্ধতি ব্যবহার করতে হবে।

Best Practice:

পাসওয়ার্ড বা সিক্রেট ইনফরমেশন সংরক্ষণ করার জন্য bcrypt বা argon2 এর মতো hashing লাইব্রেরি ব্যবহার করুন।

উদাহরণ:

import * as bcrypt from 'bcryptjs';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  private password: string;

  // Set password with hashing before saving to database
  async setPassword(password: string) {
    this.password = await bcrypt.hash(password, 10);
  }

  // Compare password
  async comparePassword(password: string): Promise<boolean> {
    return await bcrypt.compare(password, this.password);
  }
}

এখানে, পাসওয়ার্ড ইনপুট আসার পর সেটি bcrypt ব্যবহার করে হ্যাশ করা হয়েছে এবং পরে যাচাই করার জন্য comparePassword মেথড ব্যবহার করা হয়েছে।


৩. Access Control

Access control নিশ্চিত করতে হলে, আপনার অ্যাপ্লিকেশন বা API-তে ব্যবহারকারীদের অনুমতি (permissions) সঠিকভাবে সেটআপ করা উচিত। TypeORM এর relations এবং permissions সঠিকভাবে কনফিগার করা থাকলে, ব্যবহারকারীরা শুধুমাত্র তাদের অনুমতিপ্রাপ্ত ডেটা অ্যাক্সেস করতে পারবে।

Best Practice:

  • Role-based access control (RBAC) ব্যবহার করুন, যেখানে ব্যবহারকারীদের নির্দিষ্ট রোল (role) দেওয়া হবে এবং সেই রোলের উপর ভিত্তি করে তাদের অ্যাক্সেস নির্ধারণ করা হবে।
  • Access Control Lists (ACL) ব্যবহার করে সিস্টেমের সম্পদগুলোর অ্যাক্সেস নির্ধারণ করুন।

উদাহরণ:

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  role: string;  // user role like 'admin', 'user', 'guest'
}

function isAdmin(user: User): boolean {
  return user.role === 'admin';
}

এখানে, role ফিল্ড ব্যবহার করে অ্যাডমিন বা সাধারণ ব্যবহারকারীদের অ্যাক্সেস নিয়ন্ত্রণ করা হচ্ছে।


৪. Database Connection Security

ডাটাবেস সংযোগের নিরাপত্তা নিশ্চিত করা অত্যন্ত গুরুত্বপূর্ণ, বিশেষ করে যখন আপনি প্রোডাকশন ডেটাবেসের সাথে সংযুক্ত হন। ডেটাবেস কনফিগারেশনে strong credentials, SSL/TLS encryption, এবং least privilege principle অনুসরণ করা উচিত।

Best Practice:

  • Environment Variables ব্যবহার করে ডেটাবেস কনফিগারেশন, ইউজারনেম, পাসওয়ার্ড ইত্যাদি সুরক্ষিত রাখুন।
  • SSL encryption ব্যবহার করুন ডেটাবেস সার্ভার এবং ক্লায়েন্টের মধ্যে সুরক্ষিত সংযোগের জন্য।

উদাহরণ (ডেটাবেস কনফিগারেশন ormconfig.json):

{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "your-db-username",
  "password": "your-db-password",
  "database": "test_db",
  "synchronize": true,
  "logging": false,
  "ssl": true,
  "extra": {
    "ssl": {
      "ca": "path_to_ssl_certificate"
    }
  }
}

এখানে, ssl: true এবং extra.ssl কনফিগারেশন ব্যবহার করে ডেটাবেস সংযোগের জন্য SSL এনক্রিপশন সক্রিয় করা হয়েছে।


৫. SQL Injection Defense

SQL Injection থেকে সুরক্ষা নিশ্চিত করার জন্য TypeORM স্বয়ংক্রিয়ভাবে parameterized queries ব্যবহার করে, তবে নিরাপত্তার জন্য আপনাকে SQL কুয়েরি লেখার সময় সচেতন থাকতে হবে এবং কখনও সরাসরি ইউজারের ইনপুট ব্যবহার করা উচিত নয়।

Best Practice:

  • কখনোই user input সরাসরি SQL কুয়েরিতে ইনজেক্ট করবেন না।
  • TypeORM এর QueryBuilder এবং Repository মেথড ব্যবহার করে নিরাপদ কুয়েরি লেখার অভ্যাস গড়ে তুলুন।

উদাহরণ:

const users = await userRepository
  .createQueryBuilder("user")
  .where("user.name = :name", { name: userInput })
  .getMany();

এখানে, createQueryBuilder() এর মাধ্যমে parameterized query ব্যবহার করা হয়েছে, যা SQL injection থেকে সুরক্ষা নিশ্চিত করে।


সারাংশ

TypeORM ব্যবহারের সময় নিরাপত্তা নিশ্চিত করতে হলে আপনাকে বেশ কিছু best practices অনুসরণ করতে হবে। এই practices গুলির মধ্যে রয়েছে SQL Injection থেকে সুরক্ষা, Sensitive Data Encryption, Access Control সঠিকভাবে পরিচালনা, Database Connection Security, এবং parameterized queries ব্যবহার। TypeORM এর সাথে কাজ করার সময় এই নিরাপত্তা পদ্ধতিগুলি অবলম্বন করলে আপনার অ্যাপ্লিকেশন এবং ডেটাবেস আরও নিরাপদ এবং সুরক্ষিত থাকবে।

Content added By

SQL Injection কী?

SQL Injection একটি ধরনের নিরাপত্তা আক্রমণ, যেখানে আক্রমণকারী ডেটাবেসে অনিচ্ছাকৃত বা ম্যালিসিয়াস SQL কোড ইনজেক্ট করে, যা ডেটাবেসের তথ্য চুরি, পরিবর্তন, বা মুছে ফেলার কারণ হতে পারে। এটি সাধারণত ডেটাবেসে সরাসরি ইউজার ইনপুটের মাধ্যমে কোড চালানো থেকে ঘটে। SQL ইনজেকশন আক্রমণ প্রতিরোধ করা খুবই গুরুত্বপূর্ণ, বিশেষ করে যখন ইউজার থেকে ডেটা নেওয়া হয় এবং তা SQL কুয়েরিতে ব্যবহার করা হয়।

TypeORM এবং SQL Injection

TypeORM ডেটাবেস ম্যানিপুলেশন সহজ করে তোলে, তবে ডেটাবেসের নিরাপত্তা নিশ্চিত করতে কিছু সতর্কতা অবলম্বন করা জরুরি। TypeORM স্বয়ংক্রিয়ভাবে parameterized queries ব্যবহার করে, যা SQL Injection আক্রমণ থেকে সুরক্ষা নিশ্চিত করে। Parameterized queries-এ ব্যবহারকারীর ইনপুট আলাদা করে SQL কুয়েরি থেকে, যা SQL Injection আক্রমণের জন্য ঝুঁকি কমিয়ে দেয়।


TypeORM-এ Parameterized Queries ব্যবহার

Parameterized Queries হল এমন কুয়েরি, যেখানে ইউজার ইনপুট সরাসরি SQL কুয়েরির অংশ হিসেবে ব্যবহার না করে, একটি আলাদা প্যারামিটার হিসেবে ব্যবহৃত হয়। এর মাধ্যমে, SQL ইঞ্জেকশন আক্রমণ প্রতিরোধ করা যায়।

উদাহরণ ১: find এবং where মেথডের মাধ্যমে parameterized query

ধরা যাক, আপনি একটি User টেবিল থেকে ইউজারদের নাম অনুসারে ডেটা খুঁজতে চান। এখানে SQL Injection প্রতিরোধ করতে parameterized query ব্যবহার করা হচ্ছে।

import { createConnection, getRepository } from 'typeorm';
import { User } from './entity/User';

createConnection().then(async () => {
  const userRepository = getRepository(User);

  // Parameterized Query: SQL Injection থেকে সুরক্ষিত
  const user = await userRepository.findOne({ where: { name: 'John Doe' } });

  console.log(user);
}).catch(error => console.log(error));

এখানে, findOne মেথডের মধ্যে where প্যারামিটার ব্যবহার করা হয়েছে, যেখানে name এবং তার মান আলাদা করে প্রদান করা হয়েছে, যা SQL Injection আক্রমণ প্রতিরোধ করতে সাহায্য করে।


উদাহরণ ২: QueryBuilder ব্যবহার করে parameterized query

TypeORM-এ QueryBuilder ব্যবহার করে কাস্টম SQL কুয়েরি তৈরি করা যেতে পারে, এবং এতে parameterized query ব্যবহার করা যায়।

import { createConnection } from 'typeorm';
import { User } from './entity/User';

createConnection().then(async connection => {
  const userRepository = connection.getRepository(User);

  // Parameterized Query using QueryBuilder
  const user = await userRepository
    .createQueryBuilder('user')
    .where('user.name = :name', { name: 'John Doe' })
    .getOne();

  console.log(user);
}).catch(error => console.log(error));

এখানে, :name একটি প্যারামিটার হিসেবে ব্যবহৃত হয়েছে এবং এটি name: 'John Doe' এর মানের সাথে সংযুক্ত। এই পদ্ধতিতে, ইউজার ইনপুট সরাসরি SQL কুয়েরির অংশ হিসেবে যুক্ত করা হয় না, ফলে SQL Injection আক্রমণ প্রতিরোধ করা সম্ভব হয়।


TypeORM-এর SQL Injection থেকে সুরক্ষা:

  1. Parameterization: TypeORM-এর find মেথড, QueryBuilder, এবং অন্যান্য ডেটাবেস ফাংশনগুলির মধ্যে প্যারামিটারাইজড কুয়েরি ব্যবহার করে ইউজার ইনপুট SQL কুয়েরি থেকে আলাদা রাখা হয়, যা SQL Injection আক্রমণ থেকে সুরক্ষা নিশ্চিত করে।
  2. QueryBuilder ব্যবহার: TypeORM-এ QueryBuilder এর মাধ্যমে কাস্টম কুয়েরি তৈরি করা হলে, প্যারামিটারগুলি আলাদা করে ব্যবহৃত হয়, যা SQL Injection আক্রমণ থেকে সুরক্ষা দেয়। createQueryBuilder-এর মাধ্যমে আপনি কাস্টম SQL কুয়েরি তৈরি করতে পারবেন, এবং এতে প্যারামিটার দিয়ে ইনপুট মান সরবরাহ করতে পারবেন।
  3. Input Validation: TypeORM শুধুমাত্র SQL ইনজেকশন প্রতিরোধ করতে সাহায্য করে না, তবে ইউজারের ইনপুট যাচাই করার জন্য আপনি সঠিক ইনপুট ভ্যালিডেশনও করতে পারেন (যেমন, নাম, ইমেইল ইত্যাদি ফিল্ডগুলির জন্য নিয়মিত অভ্যস্ত মান চেক করা)।
  4. No Dynamic Queries: ডাইনামিক SQL কুয়েরি তৈরি করার ক্ষেত্রে সতর্কতা অবলম্বন করা উচিত। ডাইনামিক SQL কুয়েরি সাধারণত SQL Injection আক্রমণের জন্য ঝুঁকি সৃষ্টি করতে পারে, তাই প্যারামিটারাইজড কুয়েরি ব্যবহার করাই ভাল।

SQL Injection এর বিরুদ্ধে সুরক্ষিত অন্যান্য কৌশল:

  1. Prepared Statements: TypeORM-এ কাস্টম SQL কুয়েরি তৈরি করার সময় Prepared Statements ব্যবহার করতে পারেন, যা SQL কোড এবং ইউজার ইনপুটকে আলাদা করে রাখে।
  2. ORM ব্যবহার: TypeORM বা অন্য কোন ORM ব্যবহার করার মাধ্যমে ডেটাবেসের সাথে নিরাপদ যোগাযোগ নিশ্চিত করা যায়, কারণ ORM স্বয়ংক্রিয়ভাবে SQL Injection থেকে সুরক্ষা প্রদান করে।
  3. Escaping User Input: যখনই ইউজার ইনপুট নেওয়া হয়, তার মধ্যে বিশেষ ক্যারেক্টার যেমন ';-- ইত্যাদি থাকলে সেগুলিকে escape করে সুরক্ষা প্রদান করা উচিত।

সারাংশ

SQL Injection আক্রমণ প্রতিরোধ করতে TypeORM ব্যবহারকারীকে স্বয়ংক্রিয়ভাবে parameterized queries প্রদান করে। find, QueryBuilder, এবং অন্যান্য TypeORM মেথডগুলো নিরাপদভাবে SQL কুয়েরি তৈরি করার জন্য প্যারামিটারাইজড ইনপুট ব্যবহার করে, যা SQL Injection আক্রমণ প্রতিরোধে সহায়ক। TypeORM-এর মাধ্যমে সঠিকভাবে প্যারামিটারাইজড কুয়েরি ব্যবহার করে, আপনি আপনার অ্যাপ্লিকেশনকে SQL Injection আক্রমণ থেকে সুরক্ষিত রাখতে পারেন।

Content added By

Data Sanitization এবং Validation এর ভূমিকা

Data Sanitization এবং Data Validation হল ওয়েব ডেভেলপমেন্টের গুরুত্বপূর্ণ দুটি পদক্ষেপ, যা ডেটা ইনপুটের নিরাপত্তা এবং সঠিকতা নিশ্চিত করতে সাহায্য করে। TypeORM সহ যেকোনো ডেটাবেস ইন্টারঅ্যাকশনের ক্ষেত্রে, এই দুটি পদ্ধতি কার্যকরীভাবে প্রয়োগ করা অত্যন্ত গুরুত্বপূর্ণ।

  • Data Validation হল ডেটার মান যাচাই করা, অর্থাৎ নিশ্চিত করা যে, ডেটা যেটি সিস্টেমে প্রবাহিত হচ্ছে তা সঠিক এবং প্রত্যাশিত ফরম্যাটে আছে।
  • Data Sanitization হল ডেটাকে "পরিষ্কার" বা নিরাপদ করা, যেমন, বিশেষ চিহ্ন অপসারণ বা সঠিক ফরম্যাটে রূপান্তর করা, যাতে ডেটা সিস্টেমে প্রবাহিত হওয়ার আগে তা নিরাপদ হয়।

TypeORM এ Data Sanitization এবং Validation এর প্রয়োজনীয়তা

TypeORM একটি ORM (Object-Relational Mapping) লাইব্রেরি, যা ডেটাবেসের সাথে সহজে যোগাযোগ স্থাপন করতে সাহায্য করে। কিন্তু ডেটা ইনপুট করার সময় কিছু সতর্কতা অবলম্বন করা খুবই গুরুত্বপূর্ণ, যাতে সিস্টেমে ভুল বা ক্ষতিকর ডেটা প্রবাহিত না হয়। এখানে Data Validation এবং Sanitization TypeORM এর মাধ্যমে করা যেতে পারে।


১. Data Validation

ডেটা ভ্যালিডেশন হল ইনপুট ডেটার সঠিকতা এবং কার্যকারিতা যাচাই করা। Validation TypeORM এর সাথে সাধারণত class-validator প্যাকেজের মাধ্যমে সম্পন্ন করা হয়। এই প্যাকেজটি ডেটা ভ্যালিডেশনের জন্য ক্লাস ডেকোরেটর সরবরাহ করে।

class-validator ব্যবহার করে Validation

  1. class-validator ইনস্টল করা:
npm install class-validator class-transformer
  1. Entity ডেকোরেটর ব্যবহার করে Validation:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
import { IsEmail, Length } from "class-validator";

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  @Length(3, 100)
  name: string;

  @Column()
  @IsEmail()
  email: string;
}

এখানে:

  • @Length(3, 100) ডেকোরেটরটি name ফিল্ডটির জন্য মিনিমাম এবং ম্যাক্সিমাম ক্যারেক্টার সংখ্যা নির্ধারণ করছে।
  • @IsEmail() ডেকোরেটরটি email ফিল্ডটির জন্য সঠিক ইমেইল ফরম্যাট নিশ্চিত করছে।
  1. Validation ব্যবহার করার সময়:
import { validate } from "class-validator";
import { User } from "./entity/User";

const user = new User();
user.name = "Jo";
user.email = "invalid-email";

validate(user).then(errors => {
  if (errors.length > 0) {
    console.log("Validation failed: ", errors);
  } else {
    console.log("Validation succeeded!");
  }
});

এখানে, validate() ফাংশনটি ব্যবহার করে User অবজেক্টটি ভ্যালিড করা হচ্ছে এবং যদি ইনপুট সঠিক না হয়, তাহলে এটি ভ্যালিডেশন এরর দেখাবে।


২. Data Sanitization

Data Sanitization হল একটি প্রক্রিয়া যা ইনপুট ডেটার নিরাপত্তা নিশ্চিত করার জন্য বিশেষ চিহ্ন, স্পেশাল ক্যারেক্টার বা অপ্রত্যাশিত ডেটা সরিয়ে ফেলে। Sanitization TypeORM-এর সাথে সরাসরি সংযুক্ত না হলেও, আমরা সাধারণত validator এবং sanitize ফাংশন ব্যবহার করে ডেটা স্যানিটাইজ করতে পারি।

sanitize-html এবং validator ব্যবহার করে Sanitization

  1. sanitize-html এবং validator ইনস্টল করা:
npm install sanitize-html validator
  1. Data Sanitization উদাহরণ:
import * as sanitize from 'sanitize-html';
import * as validator from 'validator';

function sanitizeUserInput(input: string): string {
  // Sanitize the input to allow only basic HTML tags
  return sanitize(input, {
    allowedTags: [ 'b', 'i', 'em', 'strong', 'a' ],
    allowedAttributes: {
      'a': [ 'href' ]
    }
  });
}

function validateEmail(input: string): boolean {
  // Validate email format
  return validator.isEmail(input);
}

const userInput = "<script>alert('xss')</script><b>Valid Text</b>";
const sanitizedInput = sanitizeUserInput(userInput);
console.log(sanitizedInput); // Output: <b>Valid Text</b>

const isEmailValid = validateEmail("test@example.com");
console.log(isEmailValid); // Output: true

এখানে:

  • sanitize-html ব্যবহার করে আমরা ইনপুট থেকে স্ক্রিপ্ট ট্যাগ এবং অন্যান্য অপ্রত্যাশিত HTML ট্যাগ সরিয়ে ফেলার জন্য ডেটা স্যানিটাইজ করছি।
  • validator.isEmail() ফাংশনটি ইমেইল ইনপুট ভ্যালিডেশন নিশ্চিত করছে।

৩. Sanitization এবং Validation একত্রিত করা

ধরা যাক, আমরা একটি ইউজার ইনপুট গ্রহণ করছি এবং সেক্ষেত্রে ইমেইল এবং নাম ভ্যালিডেট এবং স্যানিটাইজ করতে চাই। নিচে একটি উদাহরণ দেওয়া হলো:

import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
import { IsEmail, Length } from "class-validator";
import * as sanitize from 'sanitize-html';
import * as validator from 'validator';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  @Length(3, 100)
  name: string;

  @Column()
  @IsEmail()
  email: string;

  // Custom method for sanitization
  sanitizeName() {
    this.name = sanitize(this.name);
  }

  // Custom method for email validation
  validateEmail() {
    if (!validator.isEmail(this.email)) {
      throw new Error('Invalid email format');
    }
  }
}

এখানে, আমরা sanitizeName() ফাংশনটি ব্যবহার করে name ফিল্ডের ইনপুট স্যানিটাইজ করছি এবং validateEmail() ফাংশনটি ব্যবহার করে ইমেইল ফিল্ডের ইনপুট ভ্যালিডেট করছি।


৪. Middleware ব্যবহার করে Sanitization এবং Validation

TypeORM বা Express.js অ্যাপ্লিকেশনে ইনপুট স্যানিটাইজেশন এবং ভ্যালিডেশন প্রক্রিয়া সাধারণত middleware এর মাধ্যমে সম্পাদন করা হয়। উদাহরণস্বরূপ, Express.js এর সাথে TypeORM ব্যবহার করলে আমরা middleware ব্যবহার করে ইনপুট ভ্যালিডেশন এবং স্যানিটাইজেশন করতে পারি।

import express from 'express';
import { User } from './entity/User';
import { validate } from 'class-validator';
import * as sanitize from 'sanitize-html';

const app = express();

app.use(express.json());

app.post('/user', async (req, res) => {
  const user = new User();
  user.name = sanitize(req.body.name);
  user.email = req.body.email;

  // Validate input data
  const errors = await validate(user);

  if (errors.length > 0) {
    return res.status(400).json(errors);
  }

  // Save user
  const userRepository = await getRepository(User);
  await userRepository.save(user);
  return res.status(201).send(user);
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});

এখানে, Express.js এর middleware ব্যবহার করে User ডেটার ইনপুট স্যানিটাইজ করা হচ্ছে এবং class-validator দিয়ে ডেটা ভ্যালিডেশন করা হচ্ছে।


সারাংশ

Data Sanitization এবং Data Validation হল নিরাপদ এবং সঠিক ডেটা ইনপুট নিশ্চিত করার জন্য অত্যন্ত গুরুত্বপূর্ণ পদক্ষেপ। TypeORM এর সাথে class-validator এবং sanitize-html প্যাকেজ ব্যবহার করে ইনপুট ডেটার সঠিকতা এবং নিরাপত্তা নিশ্চিত করা যায়। এই পদ্ধতিগুলি ডেটাবেসের সাথে কাজ করার সময় ডেটার নিরাপত্তা এবং ইন্টিগ্রিটি বজায় রাখতে সহায়তা করে, যা ওয়েব অ্যাপ্লিকেশন ডেভেলপমেন্টের জন্য খুবই গুরুত্বপূর্ণ।

Content added By

Secure Configuration এবং Environment Variables এর গুরুত্ব

Secure Configuration এবং Environment Variables ব্যবস্থাপনা এমন একটি গুরুত্বপূর্ণ বিষয় যা অ্যাপ্লিকেশনের সুরক্ষা, পোর্টেবিলিটি এবং স্কেলেবিলিটি নিশ্চিত করতে সহায়তা করে। TypeORM-এ ডেটাবেস সংযোগের মতো সংবেদনশীল তথ্য এবং কনফিগারেশন ডেটাকে সুরক্ষিতভাবে পরিচালনা করা অত্যন্ত গুরুত্বপূর্ণ। এই তথ্যগুলো যদি খোলামেলা বা অনিরাপদভাবে ব্যবহৃত হয়, তবে অ্যাপ্লিকেশনটি সুরক্ষিত থাকবে না এবং ডেটা লিক বা আক্রমণের ঝুঁকি তৈরি হতে পারে।

Environment Variables (এনভায়রনমেন্ট ভেরিয়েবলস) হলো এমন ভেরিয়েবল যা বিভিন্ন কনফিগারেশন ডেটা (যেমন API কীগুলি, ডেটাবেস সংযোগ স্ট্রিং) রাখার জন্য ব্যবহৃত হয় এবং সেগুলি পরিবেশ (environment) অনুযায়ী পরিবর্তিত হতে পারে। এগুলি কখনও কোডে হার্ডকোড করা উচিত নয়, কারণ এটি নিরাপত্তার ঝুঁকি তৈরি করতে পারে।


১. Environment Variables ব্যবস্থাপনা

Environment Variables ব্যবস্থাপনা নিশ্চিত করে যে আপনার অ্যাপ্লিকেশন কনফিগারেশন এবং সংবেদনশীল ডেটা সুরক্ষিত থাকে। সাধারণত, আপনি .env ফাইল ব্যবহার করেন, যেটি পরিবেশভিত্তিক কনফিগারেশন ডেটা রাখে।

১.১ .env ফাইল তৈরি করা

.env ফাইলটি একটি সাধারণ টেক্সট ফাইল যেখানে পরিবেশগত ভেরিয়েবলগুলো রাখার জন্য ব্যবহার করা হয়। এটি প্রজেক্টের মূল ডিরেক্টরিতে রাখা হয় এবং ডেটাবেসের ইউজারনেম, পাসওয়ার্ড, API কীগুলি ইত্যাদি সংরক্ষণ করা হয়।

উদাহরণ .env ফাইল:

DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=myusername
DB_PASSWORD=mypassword
DB_DATABASE=mydatabase

এখানে, আপনার ডেটাবেসের সংযোগের জন্য প্রয়োজনীয় সব তথ্য সুরক্ষিতভাবে .env ফাইলে রাখা হয়েছে। এই ফাইলটি সাধারণত .gitignore ফাইলে অন্তর্ভুক্ত করা হয় যাতে এটি ভার্সন কন্ট্রোলে আপলোড না হয়।

১.২ dotenv প্যাকেজ ইনস্টল করা

TypeORM-এ .env ফাইল থেকে ভেরিয়েবলগুলি ব্যবহার করার জন্য আপনি dotenv প্যাকেজটি ব্যবহার করতে পারেন। এটি .env ফাইল থেকে সকল কনফিগারেশন ভেরিয়েবল লোড করে পরিবেশে অ্যাক্সেসযোগ্য করে তোলে।

npm install dotenv

১.৩ .env ফাইল লোড করা

আপনি dotenv প্যাকেজ ব্যবহার করে .env ফাইল থেকে ভেরিয়েবল লোড করতে পারেন:

import "reflect-metadata";
import { createConnection } from "typeorm";
import * as dotenv from "dotenv";

dotenv.config();

createConnection({
  type: "postgres",
  host: process.env.DB_HOST,
  port: parseInt(process.env.DB_PORT as string),
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_DATABASE,
  entities: [
    // your entities
  ],
  synchronize: true,
}).then(connection => {
  console.log("Database connected successfully!");
}).catch(error => console.log(error));

এখানে, dotenv.config() ফাংশনটি .env ফাইলের ভেরিয়েবল লোড করেছে এবং সেগুলোকে process.env থেকে অ্যাক্সেস করা হয়েছে।


২. Configuration Handling

এছাড়া, TypeORM-এ কনফিগারেশন ম্যানেজমেন্টের জন্য আপনাকে আরও উন্নত পদ্ধতি ব্যবহার করতে হতে পারে। উদাহরণস্বরূপ, আপনি বিভিন্ন পরিবেশে (ডেভেলপমেন্ট, প্রোডাকশন, টেস্ট) আলাদা কনফিগারেশন ব্যবহার করতে পারেন।

২.১ config.ts ফাইল তৈরি করা

আপনি একটি config.ts ফাইল তৈরি করতে পারেন, যেখানে আপনার সমস্ত কনফিগারেশন লজিক থাকবে এবং পরিবেশ অনুযায়ী সঠিক সেটিংস নির্বাচন করা হবে।

import * as dotenv from "dotenv";

dotenv.config();

export default {
  type: "postgres",
  host: process.env.DB_HOST,
  port: parseInt(process.env.DB_PORT as string),
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_DATABASE,
  synchronize: process.env.NODE_ENV === "development",  // For development environment only
  logging: process.env.NODE_ENV === "development",     // Log queries in development
  entities: [
    // your entities
  ],
  migrations: [
    // your migrations
  ],
  subscribers: [
    // your subscribers
  ],
};

এখানে, আমরা কনফিগারেশন তৈরি করার সময় process.env.NODE_ENV ব্যবহার করে পরিবেশ অনুযায়ী বিভিন্ন সেটিংস নির্ধারণ করেছি। যেমন, synchronize এবং logging ডেভেলপমেন্ট পরিবেশে চালু থাকে, কিন্তু প্রোডাকশনে বন্ধ থাকবে।

২.২ TypeORM কনফিগারেশন লোড করা

এখন, TypeORM কনফিগারেশন লোড করতে এই config.ts ফাইলটি ব্যবহার করতে হবে:

import { createConnection } from "typeorm";
import config from "./config";

createConnection(config).then(() => {
  console.log("Connected to the database");
}).catch(error => console.log(error));

এখন TypeORM এই কনফিগারেশন সেটিংস ব্যবহার করবে ডেটাবেস সংযোগ করার জন্য।


৩. Security Best Practices

১. Sensitive Data Masking: ডেটাবেস বা API কীগুলির মতো সংবেদনশীল তথ্য কখনই কোডে হার্ডকোড করবেন না। এটি .env ফাইলে বা অন্য কোনো নিরাপদ স্থানে রাখতে হবে।

২. Environment-Specific Configurations: ডেভেলপমেন্ট, স্টেজিং এবং প্রোডাকশন পরিবেশের জন্য আলাদা কনফিগারেশন ব্যবহার করুন। process.env.NODE_ENV ব্যবহার করে পরিবেশের ভিত্তিতে কনফিগারেশন নির্বাচন করুন।

৩. Database Encryption: ডেটাবেসে সংরক্ষিত সংবেদনশীল তথ্য যেমন পাসওয়ার্ড এবং ইউজার ইনফরমেশন নিরাপদ রাখুন। ডেটাবেস স্তরে তথ্য এনক্রিপ্ট করুন।

৪. Disable Logging in Production: প্রোডাকশন পরিবেশে unnecessary লগিং নিষ্ক্রিয় করুন যাতে সংবেদনশীল তথ্য লগে না চলে আসে।

৫. Use SSL for Database Connection: প্রোডাকশন পরিবেশে ডেটাবেস সংযোগের জন্য SSL (Secure Socket Layer) ব্যবহার করুন, যাতে সংযোগের সময় ডেটা নিরাপদ থাকে।


সারাংশ

Secure Configuration এবং Environment Variables ব্যবস্থাপনা TypeORM এ গুরুত্বপূর্ণ ভূমিকা পালন করে, বিশেষ করে ডেটাবেস সংযোগ এবং অন্যান্য সুরক্ষিত ডেটা পরিচালনা করার ক্ষেত্রে। .env ফাইল এবং dotenv প্যাকেজ ব্যবহার করে আপনি সহজেই কনফিগারেশন এবং সুরক্ষিত তথ্য পরিচালনা করতে পারেন। TypeORM-এ বিভিন্ন পরিবেশ অনুযায়ী কনফিগারেশন নির্ধারণ করার জন্য config.ts ফাইল তৈরি করতে পারেন এবং আপনার অ্যাপ্লিকেশনের নিরাপত্তা নিশ্চিত করার জন্য কিছু সেরা অনুশীলন অনুসরণ করা প্রয়োজন।

Content added By

GraphQL এবং TypeORM এর পরিচিতি

GraphQL একটি জিজ্ঞাসা ভাষা (query language) এবং API এর জন্য একটি রানটাইম, যা ক্লায়েন্টদেরকে তাদের প্রয়োজনীয় ডেটা সুনির্দিষ্টভাবে অনুরোধ করতে সক্ষম করে। এটি REST API এর বিকল্প হিসাবে ব্যবহৃত হয়, কারণ GraphQL এ ক্লায়েন্ট শুধুমাত্র প্রয়োজনীয় ডেটা পাঠায় এবং সার্ভার শুধুমাত্র সেই ডেটা রিটার্ন করে, ফলে কার্যকরী এবং কম্প্যাক্ট ডেটা ট্রান্সফার হয়।

TypeORM একটি জনপ্রিয় ORM (Object-Relational Mapping) লাইব্রেরি যা TypeScript এবং JavaScript এর জন্য ডেটাবেস পরিচালনা সহজ করে তোলে। TypeORM ব্যবহার করলে ডেটাবেসের টেবিলগুলোকে অবজেক্ট হিসেবে ম্যাপ করা যায় এবং জটিল SQL কুয়েরি লেখার প্রয়োজন হয় না।

GraphQL এবং TypeORM এর সংমিশ্রণ Web Development-এ শক্তিশালী ডেটা ম্যানিপুলেশন এবং API প্রদান করতে পারে। এই গাইডে, আমরা দেখব TypeORM এর সাথে GraphQL কিভাবে ইন্টিগ্রেট করা যায়।


TypeORM এবং GraphQL ইন্টিগ্রেশন: একটি সাধারণ প্রক্রিয়া

১. প্রকল্প সেটআপ

প্রথমে, আমাদের Node.js এবং TypeScript ভিত্তিক একটি প্রকল্প তৈরি করতে হবে। এরপর, আমরা TypeORM, GraphQL, এবং অন্যান্য প্রয়োজনীয় লাইব্রেরি ইনস্টল করব।

১.১ Node.js প্রকল্প তৈরি করা:
mkdir typeorm-graphql-project
cd typeorm-graphql-project
npm init -y
১.২ প্রয়োজনীয় প্যাকেজ ইনস্টল করা:
npm install typeorm graphql @nestjs/graphql typeorm-graphql apollo-server-express express reflect-metadata
npm install typescript ts-node @types/node --save-dev
  • typeorm: TypeORM লাইব্রেরি ইনস্টল।
  • graphql: GraphQL লাইব্রেরি।
  • @nestjs/graphql: NestJS এর জন্য GraphQL।
  • apollo-server-express: Apollo Server যা Express এ GraphQL চালাতে সাহায্য করে।
১.৩ TypeScript কনফিগারেশন:
npx tsc --init

এটি tsconfig.json ফাইল তৈরি করবে যেখানে TypeScript কম্পাইলেশন সেটিংস কনফিগার করা হয়।


২. TypeORM কনফিগারেশন

TypeORM সেটআপের জন্য একটি ডাটাবেস কনফিগারেশন ফাইল তৈরি করতে হবে।

২.১ ormconfig.json ফাইল তৈরি করা:
{
  "type": "postgres",
  "host": "localhost",
  "port": 5432,
  "username": "postgres",
  "password": "your_password",
  "database": "your_database",
  "entities": ["src/entity/*.ts"],
  "synchronize": true
}

এখানে, আমরা PostgreSQL ডাটাবেস ব্যবহার করেছি, তবে আপনি অন্য ডেটাবেস ড্রাইভার যেমন MySQL, SQLite ইত্যাদি ব্যবহার করতে পারেন।


৩. Entity তৈরি করা

এখন একটি Entity তৈরি করা যাক, যাতে আমাদের ডাটাবেসের টেবিলের গঠন থাকে। এখানে, আমরা User নামক একটি Entity তৈরি করছি।

৩.১ User Entity তৈরি করা:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  email: string;
}

এখানে, User Entity একটি টেবিলের প্রতিনিধিত্ব করছে যেটিতে id, name, এবং email কলাম রয়েছে।


৪. GraphQL স্কিমা তৈরি করা

GraphQL স্কিমা তৈরি করার জন্য আমরা @nestjs/graphql লাইব্রেরির @ObjectType, @Field ডেকোরেটর ব্যবহার করব।

৪.১ User স্কিমা তৈরি করা:
import { ObjectType, Field, Int } from '@nestjs/graphql';

@ObjectType()
export class UserType {
  @Field(type => Int)
  id: number;

  @Field()
  name: string;

  @Field()
  email: string;
}

এখানে, আমরা UserType নামে একটি GraphQL স্কিমা তৈরি করেছি, যেটি User Entity এর মত দেখতে।


৫. Resolver তৈরি করা

Resolver হল GraphQL এ রিকোয়েস্ট হ্যান্ডল করার জায়গা, যেখানে কুয়েরি এবং মিউটেশনগুলি ব্যাখ্যা করা হয়।

৫.১ User Resolver তৈরি করা:
import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { UserType } from './user.model';
import { User } from './user.entity';
import { getRepository } from 'typeorm';

@Resolver(of => UserType)
export class UserResolver {
  @Query(returns => [UserType])
  async users(): Promise<User[]> {
    return await getRepository(User).find();
  }

  @Mutation(returns => UserType)
  async createUser(
    @Args('name') name: string,
    @Args('email') email: string,
  ): Promise<User> {
    const user = new User();
    user.name = name;
    user.email = email;
    return await getRepository(User).save(user);
  }
}

এখানে, users কুয়েরি ব্যবহার করে সব User রিটার্ন করা হয়েছে এবং createUser মিউটেশন ব্যবহার করে নতুন ব্যবহারকারী তৈরি করা হয়েছে।


৬. GraphQL Server তৈরি করা

এখন আমাদের Apollo Server ব্যবহার করে GraphQL API চালু করতে হবে।

৬.১ Apollo Server ইনস্টলেশন এবং কনফিগারেশন:
import { ApolloServer } from 'apollo-server-express';
import express from 'express';
import { buildSchema } from 'type-graphql';
import { UserResolver } from './user.resolver';
import { createConnection } from 'typeorm';

async function startServer() {
  const app = express();
  
  // TypeORM connection
  await createConnection();

  // GraphQL schema
  const schema = await buildSchema({
    resolvers: [UserResolver],
  });

  // Apollo Server setup
  const server = new ApolloServer({
    schema,
  });

  // Apply middleware to Express app
  server.applyMiddleware({ app });

  app.listen(4000, () =>
    console.log('Server is running at http://localhost:4000/graphql')
  );
}

startServer();

এখানে, আমরা ApolloServer দিয়ে GraphQL API তৈরি করছি এবং UserResolver-এ ডিফাইন করা কুয়েরি এবং মিউটেশনগুলি চালু করছি।


৭. GraphQL API টেস্ট করা

আপনার অ্যাপ্লিকেশন চালু করার পর, আপনি http://localhost:4000/graphql URL এ গিয়ে GraphQL API টেস্ট করতে পারবেন। নিচে কিছু কুয়েরি এবং মিউটেশন উদাহরণ দেওয়া হলো:

Query (সব User দেখা):
query {
  users {
    id
    name
    email
  }
}
Mutation (নতুন User তৈরি করা):
mutation {
  createUser(name: "John Doe", email: "john@example.com") {
    id
    name
    email
  }
}

সারাংশ

TypeORM এর সাথে GraphQL ইন্টিগ্রেশন Web Development-এ শক্তিশালী এবং কার্যকরী API তৈরি করতে সাহায্য করে। আপনি TypeORM ব্যবহার করে ডেটাবেসের সাথে সম্পর্কিত ডেটা পরিচালনা করতে পারেন এবং GraphQL ব্যবহার করে ক্লায়েন্টদের জন্য প্রয়োজনীয় ডেটা নির্দিষ্টভাবে এবং কার্যকরীভাবে প্রদান করতে পারেন। এই গাইডে TypeORM এবং GraphQL এর সাথে ইন্টিগ্রেশন এবং সেটআপ করার প্রক্রিয়া বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে, যাতে আপনি একটি পূর্ণাঙ্গ GraphQL API তৈরি করতে পারেন।

Content added By
Promotion

Are you sure to start over?

Loading...