কম্পিউটার টিউটোরিয়াল

সিকিউয়ার JSON Web Tokens (JWT) দিয়ে আপনার রুবি অ্যাপকে ফোর্টিফাই করুন

যদি একটি ওয়েব অ্যাপ্লিকেশন ইউজার ইনভলভ করে, স্বাভাবিকভাবে তাদের ডেটা প্রোটেক্ট এবং সিকিউর করা উচিত।

একটি ওয়েব অ্যাপ্লিকেশন সিকিউর করা অনেক কিছুর মানে হতে পারে। এই পোস্টে, আমরা ওয়েব সিকিউরিটির একটি সাবসেট আলোচনা করব যেটি JSON Web Tokens (JWTs) এবং রুবি অন রেলস ওয়েব অ্যাপ্লিকেশন ফ্রেমওয়ার্ক ব্যবহার করে অথেন্টিকেশন নিয়ে কাজ করে।

চলুন শুরু করি!

JSON Web Token কী?

একটি JSON Web Token হলো একটি ইন্টারনেট স্ট্যান্ডার্ড যা Internet Engineering Task Force (IETF) দ্বারা ডিফাইন করা হয়েছে: "দুটি পক্ষের মধ্যে ক্লেইম ট্রান্সফার করার জন্য একটি কম্প্যাক্ট, URL-safe মিনস।"

এখানে, "ক্লেইমস" সবজেক্ট সম্পর্কে বিভিন্ন ইনফরমেশন পিসকে বোঝায়। একটি ক্লেইম রিপ্রেজেন্ট করা হয় একটি নেম/ভ্যালু পেয়ার হিসেবে যেখানে নামটি সবসময় একটি স্ট্রিং, এবং ভ্যালু হতে পারে যেকোনো JSON ভ্যালু।

JSON Web Tokens-এর বেসিক স্ট্রাকচার

JWT-এর জটিলতাগুলোতে গিয়ে পড়া এই পোস্টের স্কোপের বাইরে। মheses, JWT-এর স্ট্রাকচার জানা ভালো।

একটি JWT তিনটি অংশ দিয়ে গঠিত, যেগুলো পিরিয়ড দিয়ে আলাদা: হেডার, পেলোড, এবং সিগনেচার।

একটি উদাহরণ JWT নিচের মত দেখতে পারে:


পড়ার সুবিধার্থে, টোকেনের প্রতিটি পার্ট নতুন লাইনে শুরু করা হয়েছে। প্র্যাক্টিসে, পার্টগুলো জড়িয়ে থাকে।

এই টোকেনটি সার্ভার থেকে ক্লায়েন্টে পাঠানো হয়। ক্লায়েন্ট টোকেনটি সার্ভারে পাঠায় নিজের পরিচয় দিতে এবং একটি রিকোয়েস্ট প্রসেস করাতে।

প্রথম পার্ট, হেডার, টোকেন জেনারেট করতে ব্যবহৃত অ্যালগরিদম এবং টোকেন টাইপ সম্পর্কে ইনফরমেশন ধারণ করে। যদি ডিকোড করা হয়, তবে আমরা কিছু ऐसा পাই:


দ্বিতীয় পার্ট, পেলোড, ইউজার সম্পর্কে একটি সেট ক্লেইম ধারণ করে। অধিকাংশ কেসে, এটি একটি ক্লায়েন্ট-সার্ভার সেটআপে ক্লায়েন্ট হবে, এবং এটা দেখতে পারে এমন:


সিগনেচার (একটি সাইনড JWT-এর শেষ পার্ট) টোকেনটি ভ্যালিডেট করে। এটি জেনারেট হয় হেডার এবং পেলোডকে Base64url Encoding—RFC 4648 ব্যবহার করে এনকোড করে এবং তারপর সেগুলোকে একটি পিরিয়ড সেপারেটর দিয়ে কনক্যাটেনেট করে।

সিগনেচার বিটের সাথে যেটা ঘটে সেটা মূলত এইভাবে:


HMAC_SHA256 হলো একটি কিয়েড হ্যাশ অ্যালগরিদম যা SHA-256 হ্যাশ ফাংশন থেকে কনস্ট্রাক্টেড হয়েছে যা সিগনেচার হ্যাশ করে। ক্রিপ্টোগ্রাফিক অ্যালগরिदমের চয়েন হেডারের "alg": "HS256"-এর থেকে আসে। যদি টোকেন अनসাইনড হয়, তবে শুধু হেডার এবং পেলোড থাকবে সিগনেচার ছাড়া।

আপনার রুবি অ্যাপের জন্য JWTs বনাম অন্যান্য অথেন্টিকেশন মেথড

JSON Web Tokens, নামটিই ইঙ্গিত দিচ্ছে, টোকেন-ভিত্তিক। অন্য প্রান্তে, у нас আছে সেশন-ভিত্তিক অথেন্টিকেশন: ইউজার অথেন্টিকেশন করার একটি আরও ট্রাডিশনাল পদ্ধতি। সেশন-ভিত্তিক অথেন্টিকেশন-এর ফ্লো টোকেন-ভিত্তিক অথেন্টিকেশন থেকে পুরোপুরি ভিন্ন।

সেশন-ভিত্তিক অথেন্টিকেশন ফ্লো দেখতে পারে এমন:

  1. একজন ইউজার বা ক্লায়েন্ট একটি রিকোয়েস্ট পাঠায় যেটে ইউজার ক্রেডেনশিয়াল থাকে।
  2. সার্ভার ইউজারকে অথেন্টিকেট করে, একটি সেশন স্টোর করে, এবং একটি সেশন আইডি রিটার্ন করে যা ব্রাউজারে কুকি হিসেবে স্টোর হয়।
  3. ক্লায়েন্ট এরপরবর্তী রিকোয়েস্টগুলোর সাথে কুকিজ পাঠায় সার্ভারে।
  4. সার্ভার প্রেজেন্ট করা সেশন ইনফরমেশন ইন্সপেক্ট করে এবং, যদি বৈধ হয়, ইউজারকে অথেন্টিকেট করে এবং রিকোয়েস্ট করা ইনফরমেশন ক্লায়েন্টকে রিটার্ন করে।

যেখানে সেশন-ভিত্তিক অথেন্টিকেশন অধিকাংশ ক্লায়েন্ট-সার্ভার কানেকশনের জন্য ব্যবহার হয়, সেখানে টোকেন-ভিত্তিক অথেন্টিকেশন প্রায়শই সার্ভার-টু-সার্ভার কানেকশনে ব্যবহার হয় (যেন, দুটি API-এর মাঝপথে)।

একটি গুরুত্বপূর্ণ পার্থক্য লক্ষ্য করুন, য전에 সেশন-ভিত্তিক অথেন্টিকেশনে, অথেন্টিকেশন স্টেট সার্ভারে হ্যান্ডেল হয়—যখন টোকেন ক্লায়েন্টে ম্যানেজ হয়।

অথেন্টিকেশনের জন্য JWTs কেন ব্যবহার করবেন?

নামাতেই ইমপ্লিমেন্ট করা সাপেক্ষিক সহজ হলো, JSON Web Tokens অথেন্টিকেশনের জন্য ব্যবহার করার আরো কয়েকটি সুবিধা আছে, যেন:

  • এরা স্টেটলেস, অর্থাৎ একটি সেশন স্টোর প্রয়োজন নেই। টোকেনটিই সকল ইউজার ইনফরমেশন ধারণ করে, তাই প্রতিটি রিকোয়েস্টে ডাটাবেস বা অথেন্টিকেশন সার্ভার কুয়েরি করার প্রয়োজন নেই।
  • JWTs সাধারণত অধিক পারফরম্যান্ট περισσাংশ ট্রাডিশনাল অথেন্টিকেশন মেথডের চেয়ে (যতক্ষণ না সার্ভার ডাটাবেস বা স্টোরের বিরুদ্ধে কোনো লুকআপ করে ইউজার অথেন্টিকেট করে), এতে এফিশিয়েন্ট।
  • এরা স olid সিকিউরিটি গ্যারান্টিও অফার করে, যেন সাইনড JWTs সফগার্ড প্রদান করে যাতে কোনো অ্যাটাকার বা ক্লায়েন্ট টোকেন মডিফাই করে প্রোটেক্টেড ডেটা এক্সেস করতে না পারে।

রুবি অ্যাপের জন্য JWT বেস্ট প্র্যাকটিস

JWT সাইন করতে ব্যবহৃত সিক্রেট কীগুলো লম্বা, র‍্যান্ডম, এবং কমপ্লেক্স ক্যারেক্টার কম্বিনেশন دارাত্ব হওয়া উচিত। এটা নিশ্চিত করে যে কীগুলো পর্যাপ্ত সেফ এবং অ্যাটাকাররা ব্রুট-ফোর্স করে সেগুলো کر্যাক করতে পারে না।

রেলস যে সিক্রেট কীগুলো জেনারেট করে সেগুলো অধিকাংশ কেসে সেফ, কিন্তু সেফটি গ্যারান্টি নালিফাইড হয়ে যায় যদি আপনি ভুলবশত কীগুলো কমিট করে রিভিল কর দেন।

নেটওয়ার্কে দুটি পক্ষের মাঝপথে টোকেন ট্রান্সপোর্ট করার সময় Transport Layer Security (TLS) ব্যবহার করা కూడా গুরুত্বপূর্ণ। TLS ম্যান-ইন-দ-মিডল অ্যাটাক কমiatric করতে পারে (টোকেন এবং সেশন-ভিত্তিক উভয় অথেন্টিকেশন মেথডই এমন অ্যাটাকের প্রতি আতঙ্কিত)।

একটি রেলস অ্যাপে JWT অথেন্টিকেশন ইমপ্লিমেন্ট করা

একটি টোকেন-ভিত্তিক অথেন্টিকেশন ফ্লো দেখি:

সিকিউয়ার JSON Web Tokens (JWT) দিয়ে আপনার রুবি অ্যাপকে ফোর্টিফাই করুন

সেশন-ভিত্তিক অথেন্টিকেশনের বিপরীতে, একটি স্টেটফুল অথেন্টিকেশন টেকনিক যেখানে আমরা সেশন ব্যবহার করি একটি অথেন্টিকেটেড ইউজার ট্র্যাক রাখতে, JWT-সহ টোকেন-ভিত্তিক অথেন্টিকেশন স্টেটলেস; সার্ভারে ইউজার অথেন্টিকেশন স্টেট সম্পর্কে যেকোনো ইনফরমেশন স্টোর করার প্রয়োজন নেই। এটি অ্যাপ্লিকেশন ডিজাইনকে সহজ করে তোলে।

এই পোস্টে, আমরা অনুমান করব আমাদের অ্যাপ্লিকেশন একটি ফ্রন্টএন্ড এবং একটি ব্যাকএন্ডে ভাগ করা। অথেন্টিকেশন ব্যাকএন্ডে হয়, তাই আমরা একটি রেলস API ব্যাকএন্ড অথেন্টিকেশনসহ বানাব।

এই পোস্টের স্যাম্পল কোড রেলস ৭.০.৫ এবং রুবি ৩.২.২-ভিত্তিক।

jwt এবং bcrypt রুবি জেম ব্যবহার করা

আমাদের অ্যাপ্লিকেশনের জন্য দুটি জেম দরকার: jwt এবং bcrypt।

jwt হলো RFC 7519 OAuth JSON Web Token স্ট্যান্ডার্ডের একটি রুবি ইমপ্লিমেন্টেশন। bcrypt হলো OpenBSD bcrypt() পাসওয়ার্ড হ্যাশিং অ্যালগরিদমের একটি রুবি বাইন্ডিং।

আপনি এই কোড রেপোতে স্যাম্পল কোড ফলো করতে পারেন।

নোট: jwt JWT-র সাথে কাজ করার একমাত্র সমাধান নয়; আরেকটি জনপ্রিয় জেম হলো devise-jwt, যা Devise এবং রেলসের জন্য JWT অথেন্টিকেশন প্রদান করে। কিন্তু এই পোস্টে আমরা jwt-এ ফোকাস করব।

চলুন শুরু করি।

আমাদের রেলস API বানানো

প্রথমে যা দরকার সেটা একটি API অ্যাপ্লিকেশন। আমরা এটাকে তৈরি করব:


এখানে --api অপশনটি শুধু API অ্যাপ্লিকেশনের জন্য একটি ছোট রেলস স্ট্যাক প্রি-কনফিগার করে।

Gemfile-এ, আমরা আমাদের প্রথম ডিপেন্ডেন্সি, jwt যোগ করতে পারি। আমাদের দ্বিতীয় জেম, bcrypt, একটি নতুন জেনারেট করা রেলস অ্যাপ্লিকেশনের Gemfile-এ ইতিমধ্যে আছে—আমাদের শুধু আনকমেন্ট করতে হবে।

আমাদের ডাটাবেসে ইউজার পাসওয়ার্ড সিকিউরলি হ্যাশ করার জন্য bcrypt দরকার। এটা নোট করা গুরুত্বপূর্ণ যে আমরা bcrypt ডায়রেক্টলি ব্যবহার করব না। আমরা Active Model-এর has_secure_password ক্লাস মেথড লিভারেজ করব, যা bcrypt-এর ওপর ডিপেন্ডেন্ট।

ডিফল্ট জেমগুলো যেগুলো একটি নতুন রেলস অ্যাপ্লিকেশনের সাথে আসে সেগুলো ইগনোর করলে, আমাদের Gemfile দেখতে হবে এমন:


এখন আমাদের জেমগুলো bundle install দিয়ে ইনস্টল করার ভালো সময়।

User এবং Product মডেল জেনারেট করা

এরপর, আমরা দুটি মডেল জেনারেট করব: User এবং Product। User হবে ইউজারদের রিপ্রেজেন্ট করার মডেল এবং আমরা এটাকে অথেন্টিকেট করব প্রোডাক্টস অ্যাক্সেস করার অনুমতি দিতে, যেগুলো Product মডেল দ্বারা রিপ্রেজেন্ট করা হয়।


rails db:migrate দিয়ে আমাদের মাইগ্রেশন রান করার পর, মডেলসহ আমাদের সেটআপ কমপ্লিট, এবং db/schema.rb-এ পাওয়া যাওয়া আমাদের স্কিমা এখন দেখতে হবে এরকম:


এই পর্যায়ে ইঙ্গিত করা গুরুত্বপূর্ণ যে আমরা ইচ্ছাক্রমে পটেনশিয়াল ইস্যু যেন ডাটাবেস কনস্ট্রেইন্টস, ভ্যালিডেশন, ইউনিকনেস নিশ্চিত করা ইত্যাদি ইগনোর করছি। এই পোস্টের জন্য, আমরা এরর হ্যান্ডলিং ইত্যাদি ডিসরিগার্ড করছি। আমাদের উদ্দেশ্য এখানে JWTs-কে একটি স্টেটলেস অথেন্টিকেশন ফর্ম হিসেবে ডেমো করানো যা আমাদের রুবি অ্যাপ্লিকেশন সিকিউর করে। একটি প্রোডাকশন অ্যাপ্লিকেশনে, আপনি চাইবেন এই সকল কভার করা হয়।

একটি jwt জেম র‍্যাপার বানানো

পরবর্তী ধাপ হলো আমরা আগে ইনস্টল করা jwt জেমের চারপাশে একটি র‍্যাপার বানানো। আমরা এই র‍্যাপার ব্যবহার করব সার্ভার থেকে ক্লায়েন্টে ক্লেইম এনকোড ও ডিকোড করতে। এর জন্য, আমরা একটি app/lib ফোল্ডার তৈরি করব।

আমরা রেলসের সাথে আসা lib ফোল্ডার ব্যবহার করছি না কারণ এটি অটোলোডেড নয়। app আন্ডারের সবকিছু ডিফল্টভাবে অটোলোডেড এবং ইগারলোডেড, যা আমাদের কেসে সেটআপকে সিম্পল করে।

আমাদের র‍্যাপার ক্লাস app/lib/json_web_token.rb-এ পাওয়া যাবে এবং দেখতে হবে এরকম:


এখানে প্রধান মেথডগুলো হলো encode—ইউজার ইনফরমেশন এনকোড করতে—এবং decode—বादে সার্ভারে ইউজার ইনফরমেশন ডিকোড করতে। লক্ষ্য করুন কীভাবে আমরা এনকোডিং ও ডিকোডিং টাস্ক jwt জেমের কাছে JWT.encode এবং JWT.decode দিয়ে ডেলিগেট করছি।

এই পয়েন্টে, আপনি ইতিমধ্যে আপনার রেলস কনসোলে এই ক্লাস টেস্ট করতে পারেন:


লক্ষ্য করুন কীভাবে JsonWebToken.encode(data)-র রেজাল্ট পিরিয়ড দিয়ে তিনটি পার্টে ভাগ হয়েছে, হেডার, পেলোড, এবং সিগনেচার প্রোডিউস করছে। আমাদের সিগনেচার বিট আছে কারণ আমরা আমাদের পেলোডকে একটি সিক্রেট কী দিয়ে সাইন করেছি যা রেলস Rails.application.secrets.secret_key_base দিয়ে প্রদান করে।

ফিরে User মডেলে

এখন app/models/user.rb-এ আমাদের User মডেলে ফিরে যাওয়ার ভালো সময়। এখানে আমাদের শুধু has_secure_password ক্লাস মেথড যোগ করতে হবে:


has_secure_password আমাদের ইউজারদের পাসওয়ার্ড ডাটাবেসে সিকিউরলি হ্যাশ করে।

রেলসে একটি স্যাম্পল ইউজার এবং প্রোডাক্ট তৈরি করা

এখন আমরা রেলস কনসোলে হপ করতে পারি একটি স্যাম্পল ইউজার এবং প্রোডাক্ট আমাদের ডাটাবেসে জেনারেট করতে এবং আমাদের অ্যাপ্লিকেশনের সিকিউরিটি টেস্ট করতে:


আপনি একই কোড টুকরো আপনার seeds.rb ফাইলে রাখতে পারেন কিছু টাইপিং বাঁচাতে যদি আপনি আপনার ডাটাবেস রিসেট করেন।

রেলস কন্ট্রোলারে JWTs ব্যবহার করা

পরবর্তী স্টেপগুলোতে, আমরা JWTs ব্যবহার করে আমাদের কন্ট্রোলারে সিকিউরিটি ইমপ্লিমেন্ট করব। শুরু করার একটি ভালো জায়গা app/controllers/application_controller.rb-এ ApplicationController:


এখানে, আমরা একটি authenticate মেথড তৈরি করছি যা ইউজাররা আমাদের পাঠানো JSON Web টোকেন ডিকোড করে। যদি আমরা সফলভাবে টোকেন ভেরিফাই করতে পারি, তবে আমরা সেই User অবজেক্ট রিটার্ন করব যা রিকোয়েস্ট করা ইউজারকে রিপ্রেজেন্ট করে। আমরা অধিকাংশত হ্যাপি পাথ-এ আগ্রহী এবং অনেক চেক বাইপাস করব।

ApplicationController-এ authenticate মেথড ডিফাইন করে এবং সেটাকে একটি before_action হিসেবে সেট আপ করলে এটি থেকে ইনহেরিট করা সব কন্ট্রোলার সিকিউর হয়ে যাবে। অন্য যেকোনো কন্ট্রোলারের রিকোয়েস্টে একটি বৈধ JWT প্রয়োজন হবে সেসব কন্ট্রোলার অ্যাক্সেস করতে (কারণ সকল অন্য কন্ট্রোলার এই মেইন কন্ট্রোলার থেকে ইনহেরিট করবে)।

এরপর, আমাদের একটি AuthenticationController দরকার যেন ইউজাররা রিকোয়েস্ট পাঠাতে পারে এবং আমাদের সার্ভার থেকে একটি সাইনড JSON Web Token পেতে পারে। এই কন্ট্রোলার app/controllers/authentication_controller.rb-এ থাকবে এবং দেখতে পারে এরকম:


যখন এই কন্ট্রোলারে একটি রিকোয়েস্ট হিট করে, যেহেতু এটি একটি ইউজার টোকেন চাইছে, আমরা আপনি প্রাথমিকভাবে তাদের অথেন্টিকেট করতে চাই না। এই কন্ট্রোলারটির উদ্দেশ্য হলো একটি টোকেন দিয়ে রেসপন্ড করা যা ইউজার ব্যবহার করতে পারবে আমাদের সার্ভারের বাকি রিসোর্স অ্যাক্সেস করতে। তাই দরকার skip_before_action :authenticate দ্বিতীয় লাইনে।

login অ্যাকশনে (যেটা ইউজাররা টোকেন পেতে হিট করে), আমরা রিকোয়েস্টের সাথে আসা প্যারামিটার থেকে username এবং password গ্র্যাব করি। যদি আমরা ইউজারকে অথেন্টিকেট করতে পারি—অর্থাৎ, যাচাই করতে পারি তাদের ইউজারনেম এবং পাসওয়ার্ড আমাদের ডাটাবেসে স্টোর করা ডেটার সাথে মেলে—তাহলে আমরা তাদের একটি সাইনড টোকেন এবং সেই টোকেন কবে এক্সপায়ার হবে সেটা সম্পর্কে ইনফরমেশন প্রেজেন্ট করি।

আমাদের কেসে, আমরা টোকেনের এক্সপায়ারি পিরিয়ড ব্যবহার করব না। কিন্তু একটি প্রোডাকশন অ্যাপ্লিকেশনে, সেটাকে একটি রিসোর্সে অ্যাক্সেস রিভোক করতে ব্যবহার করা যেতে পারে।

আমরা এই সকল স্টেপ curl ব্যবহার করে যাব।

একটি প্রোটেক্টেড রিসোর্স দিয়ে আমাদের রুবি অ্যাপ্লিকেশন টেস্ট করা

আমরা আংশিকভাবে 'রেলস অ্যাপে JWT অথেন্টিকেশন ইমপ্লিমেন্ট করা' সেকশনের ফ্লো ডায়াগ্রামে ফ্লো কভার করেছি। সকল স্টেপ কমপ্লিটলি কভার এবং ফ্লো ডায়াগ্রামের সকল স্টেপ টেস্ট আউট করতে, আমাদের একটি রিসোর্স দরকার যেটা প্রোটেক্টেড।

আমাদের একটি Product মডেল আছে। এখন আমাদের প্রোডাক্ট মডেলের জন্য একটি কন্ট্রোলার এবং প্রোডাক্ট ও টোকেন অ্যাক্সেস করার রাউটস দরকার।

চলুন rails g controller Product index দিয়ে একটি কন্ট্রোলার তৈরি করি যাতে আমাদের এমন কিছু থাকে:


অবশ্য, এই কন্ট্রোলারগুলো অ্যাক্সেস করার জন্য রাউট দরকার। আমাদের config/routes.rb দেখতে হবে এরকম:


এখন আমরা curl দিয়ে টেস্ট করব সবকিছু এক্সপেক্টেডভাবে কাজ করছে কিনা। লক্ষ্য করুন, আমাদের ইতিমধ্যে একটি ইউজার আছে অথেন্টিকেশন করার জন্য এবং একটি প্রোডাক্ট রিসোর্স আছে অ্যাক্সেস করার জন্য।

চলুন একটি অস্তিত্বহীন ইউজারের সাথে JWT পাওয়ার চেষ্টা করি:


আমাদের নিচের রেসপন্স পাওয়া উচিত:


এখন আগে তৈরি করা ইউজারের সাথে একই চেষ্টা করি:


এটি আমাদের একটি সাইনড JSON ওয়েব টোকেন দেবে যা দেখতে পারে এমন:


এই টোকেনটি একসেকেন্ড ধরে রাখি এবং একটি খারাপ টোকেন দিয়ে প্রোডাক্ট রিসোর্স অ্যাক্সেস করার চেষ্টা করি (টোকেনের একটি র‍্যান্ডম ক্যারেক্টার চেঞ্জ করলাম):


আমাদের পাওয়া উচিত:


তবে, যদি আমরা আগে সার্ভার থেকে পাওয়া বৈধ টোকেন দিয়ে একই রিকোয়েস্ট করি প্রোডাক্ট রিসোর্স অ্যাক্সেস করতে:


আমাদের প্রোডাক্ট রিসোর্সে অ্যাক্সেস প্রদান করা হয়েছে:


হয়ে গেলো! আমরা সফলভাবে আমাদের রুবি অ্যাপ্লিকেশনকে একটি JSON ওয়েব টোকেন দিয়ে সিকিউর করেছি!

শেষ কথা

এই পোস্টে, আমরা JSON Web Tokens এবং সেগুলো কীভাবে কাজ করে সেটা আলোচনা করেছি। আমরা প্রথমে JWT-এর বেসিকস কভার করেছি, যার মধ্যে এর স্ট্রাকচার এবং কিছু বেস্ট প্র্যাকটিস। তারপর আমরা jwt জেম ব্যবহার করে একটি সিম্পল JWT অথেন্টিকেশন ইমপ্লিমেন্ট করেছি।

আশা করি আপনি এই পোস্টটি হেল্পফুল পেয়েছেন। হ্যাপি কোডিং!

P.S. রুবি ম্যাজিক পোস্টগুলো প্রেস থেকে বের होते সাথে পেতে চাইলে আমাদের রুবি ম্যাজিক নিউজলেটার সাবস্ক্রাইব করুন এবং একটিও পোস্ট মিস করবেন না!

  1. Redis SISMEMBER: সেট সদস্যতা যাচাই করার দ্রুত পদ্ধতি

  2. জাভাতে JFrame এবং JDialog-এর পার্থক্য কী?

  3. C++ প্রোগ্রামে লম্বকোণী ত্রিভুজের হাইপোটেনাস দিয়ে সার্কামসার্কেলের ক্ষেত্রফল

  4. AngularJS – isUndefined() মেথড