Laravel Security
Authorization with Laravel Gates
Laravel Framework এ রয়েছে একটি শক্তিশালী এবং ফ্লেক্সিবল authorization system যা ডেভেলপারদের বিভিন্ন মানদণ্ডের উপর ভিত্তি করে রিসৌর্স গুলিতে অ্যাক্সেস নিয়ন্ত্রণ করতে দেয়। লারাভেল authorization system দুটি বিষয়ের উপর ভিত্তি করে তৈরি। এর একটি হচ্ছে Laravel Gates এবং অন্যটি হচ্ছে Policies. আজকে আমরা দেখব কিভাবে Gates ব্যবহার করে কিভাবে Laravel Framework দিয়ে তৈরি web application এ authorization system বাস্তবায়ন করা যায়।
Laravel Framework এ Gates কি?
Laravel Framework বিভিন্ন কাজের অনুমোদনের দুটি প্রাথমিক উপায় প্রদান করে: একটি হচ্ছে gates এবং আর অন্যটি হচ্ছে policies. Laravel Framework এ , Gates Authorization হল এমন একটি ফীচার যা আপনাকে আপনার অ্যাপ্লিকেশনের মধ্যে নির্দিষ্ট ক্রিয়া বা রিসৌর্স গুলিতে Access Control করতে custom authorization logic ডিফাইন করতে দেয়। Gates authorization এর জন্য একটি সহজ, closure-ভিত্তিক Method প্রদান করে Gates এবং Policies গুলো সাধারণত app/providers/AuthServiceProvider ক্লাসে ডিফাইন করা থাকে এবং সেগুলি আপনার controllers, routes বা views তে ব্যবহার করা যেতে পারে যে কোনও ইউজার একটি নির্দিষ্ট কাজ সম্পাদনের জন্য অনুমোদিত কিনা তা পরীক্ষা করতে। এই পর্বে, আমরা প্রথমে Gates এক্সপ্লোর করব এবং পরীক্ষা করব৷
একটি অ্যাপ্লিকেশন তৈরি করার সময় আপনাকে শুধুমাত্র gates ব্যবহার করা বা শুধুমাত্র policies ব্যবহার করতে হবে , এমন কোনো বাধ্যবাদকতা নেই৷ বেশিরভাগ অ্যাপ্লিকেশনে অনেক ক্ষেত্রেই gates এবং policies একই সাথে ব্যবহার হতে পারে এবং এটি আরো বেশি কার্যকর! gates সাধারণত সবচেয়ে বেশি প্রযোজ্য এমন কাজ গুলির জন্য যা কোনও মডেল বা রিসোর্সের সাথে সম্পর্কিত নয়, যেমন একটি administrator dashboard দেখা৷ অন্যদিকে , policies গুলি ব্যবহার করা উচিত যখন আপনি একটি নির্দিষ্ট মডেল বা রিসোর্সের জন্য একটি কাজ authorize করতে চান৷
Gates Authorization কখন ব্যবহার করবেন?
Laravel Gates Authorization ব্যবহার করা হয় যখন আপনার Laravel অ্যাপ্লিকেশনের মধ্যে নির্দিষ্ট কিছু অ্যাকশন বা রিসোর্সে অ্যাক্সেস নিয়ন্ত্রণ করতে হয়। এটি custom authorization logic সংজ্ঞায়িত করার একটি উপায় প্রদান করে এবং নির্দিষ্ট শর্তের উপর ভিত্তি করে একজন ইউজারকে একটি নির্দিষ্ট ক্রিয়া সম্পাদন করার অনুমতি দেওয়া হয় কিনা তা নির্ধারণ করে। এখানে কিছু পরিস্থিতি রয়েছে যখন আপনি Laravel Gates Authorization ব্যবহার করতে চাইতে পারেন:
- Resource Authorization:
- Custom Authorization Logic:
- Conditional Access Control:
- Fine-Grained Access Control:
- Authorization in Views:
- Authorization in Controllers and Routes:
- Complex Multi-Step Authorization:
যখন আপনি user roles বা ownership এর উপর ভিত্তি করে নির্দিষ্ট রিসৌর্স গুলিতে অ্যাক্সেস নিয়ন্ত্রণ করতে চান (যেমন, models)। উদাহরণস্বরূপ, আপনি শুধুমাত্র একটি post owner কে এটি edit বা delete করে ফেলার অনুমতি দিতে চাইতে পারেন৷
যখন আপনার আরও complex এবং customized authorization rules এর প্রয়োজন হয় যা শুধুমাত্র লারাভেলের built-in authorization ফীচার গুলির (যেমন, policies এবং middleware) দিয়ে অর্জন করা যায় না। Gates আপনাকে ক্লোজার ব্যবহার করে কাস্টম লজিক ডিফাইন করতে দেয়, আপনাকে একটি ইউনিক পরিস্থিতিতে হ্যান্ডেল করার ফ্লেক্সিবিলিটি দেয়।
যখন আপনি dynamic condition গুলোর উপর ভিত্তি করে নির্দিষ্ট ক্রিয়াকলাপে অ্যাক্সেস সীমাবদ্ধ করতে চান। উদাহরণস্বরূপ, আপনি একটি নির্দিষ্ট role বা permission সহ ইউজারদের শুধুমাত্র একটি নির্দিষ্ট সময়ের মধ্যে একটি ফীচার এ অ্যাক্সেস করার অনুমতি দিতে চাইতে পারেন।
যখন আপনার অ্যাপ্লিকেশানে fine-grained access control প্রয়োগ করতে হবে। Gates আপনাকে নির্দিষ্ট permissions এবং roles গুলি পরীক্ষা করার অনুমতি দেয়, আপনাকে একটি granular level এ অ্যাক্সেস কন্ট্রোল করতে সক্ষম করে।
যখন আপনি ইউজারের roles বা permissions এর উপর ভিত্তি করে আপনার views গুলিতে কিছু elements show বা hide করতে চান। শর্তসাপেক্ষে content রেন্ডার করতে আপনি Blade templates এ @can directive ব্যবহার করতে পারেন।
আপনি যখন unauthorized access থেকে নির্দিষ্ট কিছু routes বা controller actions গুলিকে প্রটেক্ট করতে চান। controller বা route middleware এ gates ব্যবহার করা unauthorized ইউজারদের নির্দিষ্ট ক্রিয়া সম্পাদন থেকে আটকাতে সাহায্য করে।
যখন আপনার অ্যাপ্লিকেশনের multi-step authorization চেকের প্রয়োজন হয়, তখন ইউজার authorized কিনা তা নির্ধারণ করতে gates একাধিক চেক একসাথে চেইন করার জন্য কার্যকর হতে পারে।
লারাভেলের Gates Authorization একই সাথে policies এবং middleware এর মতো অন্যান্য built-in authorization ফীচার গুলির পাশাপাশি ভাল কাজ করে। Policies গুলি সাধারণত মডেলের উপর ভিত্তি করে authorization এর জন্য ব্যবহৃত হয়, আর অন্যদিকে middleware সম্পূর্ণ routes বা routes গ্রুপগুলিকে রক্ষা করতে পারে। Gates আরো নির্দিষ্ট, শর্ত-ভিত্তিক authorization এর জন্য ফ্লেক্সিবিল একটি অতিরিক্ত লেয়ার প্রদান করে।
Laravel Gates কে কার্যকরভাবে ব্যবহার করে, আপনি নিশ্চিত করতে পারেন যে আপনার অ্যাপ্লিকেশনটি যথাযথ অ্যাক্সেস নিয়ন্ত্রণগুলি প্রয়োগ করে, নিরাপত্তার সর্বোত্তম অনুশীলনগুলি মেনে চলে এবং অথরাইজড ইউজারদের শুধুমাত্র প্রাসঙ্গিক ফীচার এবং কনটেন্ট দেখানোর মাধ্যমে একটি ধারাবাহিক ইউজার এক্সপেরিয়েন্স প্রদান করে।
Install Fresh Laravel For Gates Authorization
তো চলুন তার আগে আমরা একটা ফ্রেশ লারাভেল ইনস্টল করে ফেলি। আপনার পি সি তে যদি ইতিমধ্যে কোনো লারাভেল ইনস্টল না থাকে তাহলে প্রথমে কম্পোজার এর মাধ্যমে নিম্নোক্ত কমান্ড ব্যবহার করে লারাভেল টি ইনস্টল করে ফেলুন :
composer global require laravel/installer
একবার কম্পোজার গ্লোবালি ইনস্টল হয়ে গেলে, নিম্নোক্ত আর্টিসান কমান্ড ব্যবহার করে একটি নতুন লারাভেল প্রজেক্ট তৈরি করুন:
laravel new your-project-name
এবার আপনার লারাভেল প্রজেক্টের , .env ফাইলটি খুলুন এবং আপনার ডাটাবেস বিষয়ক প্রয়োজনীয় সেটিংস সেট করুন। উদাহরণ স্বরূপ:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=your_database_name DB_USERNAME=your_database_username DB_PASSWORD=your_database_password
এরপরে, authentication এর জন্য প্রয়োজনীয় টেবিল তৈরি করতে database migrations রান করুন :
php artisan migrate
এবার Laravel authentication scaffolding install করার পালা। Laravel Framework এর জন্য একটি ui আর্টিসান কমান্ড প্রদান করে। আপনি একাধিক front-end presets যেমন “bootstrap,” “vue,” “react,” বা “none” (কোনও preset না করতে চাইলে) থেকে যেকোনো একটি বেছে নিতে পারেন ।
উদাহরণস্বরূপ, আপনি যদি আপনার front-end এর জন্য Bootstrap ব্যবহার করতে চান, তাহলে আর্টিসান কমান্ড টি হবে নিম্নরুপঃ
composer require laravel/ui php artisan ui bootstrap --auth
এটি authentication এর জন্য প্রয়োজনীয় views, controllers এবং routes ইনস্টল করবে।
এবার আপনার fron-end assets যেমন CSS বা JavaScript গুলি কম্পাইল করতে হবে। আর এর জন্য আপনাকে নিম্নলিখিত কমান্ড চালাতে হবে :
npm install && npm run dev
এবার মূল কাজে আসা যাক:
ধরুন আপনার একটি ওয়েবসাইট আছে এবং শুধুমাত্র সাবস্ক্রাইবাররাই অ্যাক্সেস করতে পারে এমন কনটেন্ট দেখাতে চান। তাহলে, কিভাবে আপনি ইউজারদের রেস্ট্রিক্ট করবেন এবং শুধুমাত্র সাবস্ক্রাইবারদের অ্যাক্সেস প্রদান করবেন?
আসুন users table এ ‘subscribe’ নামে আরেকটি কলাম যোগ করি। আর এর মান একটি বুলিয়ান হবে। সাবস্ক্রাইব না করা ইউজারদের জন্য subscribe কলামের মান ০ এবং সাবস্ক্রাইব করা ইউজারদের জন্য subscribe কলামের মান 1 দেওয়া হবে।
এটি করার জন্য, একটি নতুন মাইগ্রেশন ফাইল তৈরি করতে নিম্নলিখিত আর্টিসান কমান্ডটি চালান:
php artisan make:migration add_subscribe_to_users_table --table=users
এরপরে, database/migrations/
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::table('users', function (Blueprint $table) { $table->boolean('subscribe')->default(0); }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('users', function (Blueprint $table) { $table->dropColumn('subscribe'); }); } };
এরপরে, আপনার সদ্য তৈরি এবং আপডেট করা মাইগ্রেশন ফাইলটিকে নিম্নোক্ত artisan কমান্ড দিয়ে রান করুন:
php artisan migrate --path=/database/migrations/<timestamp>_add_subscribe_to_users_table.php
উপরের মাইগ্রেশনটি রান করার ফলে users টেবিলে একটি বুলিয়ান ফিল্ড হিসাবে একটি নতুন subscribe field যুক্ত হবে যার একটি ডিফল্ট মান থাকবে 0.
সবশেষে, আমরা একটি প্রদত্ত ইউজারের জন্য subscribe ফিল্ডের ডিফল্ট মান আপডেট করব। এটি করার জন্য, আপনার পছন্দের ডাটাবেস টুলে ডাটাবেস খুলুন, users টেবিলে, আপনার পছন্দসই ইউজারের জন্য subscribe কলামটিতে নতুন মান 1 সেট করুন।
এখন চলুন আমাদের project কে এগিয়ে নিয়ে যাই।
Gates এর ব্যবহার
আমরা যা অর্জন করতে চাই তা হল যখন একজন ইউজার সাবস্ক্রাইব হয়, ইউজার লগইন করার পরে, “Laravel” লিঙ্কে ক্লিক করলে “Home” লিঙ্কের পাশে ‘Subscribers’ নামে একটি অতিরিক্ত লিঙ্ক উপস্থিত হবে৷ এই লিঙ্কটি সেই সমস্ত ইউজারদের কাছে দৃশ্যমান হবে যারা কনটেন্ট দেখার জন্য সাবস্ক্রিপশন নিয়েছেন৷
তাই প্রথম যে জিনিসটি আমরা যোগ করব তা হলো link টি। এটি করতে আমাদেরকে , resources/views/welcome.blade.php-এ নেভিগেট করতে হবে এবং আমাদের homepage লিঙ্কের ঠিক নীচে, আমরা এটি যোগ করব:
/ <a href="{{ url('/subscribe') }}" class="font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500">Subscribers</a>
এখন আমাদের subscribe route তৈরি করা যাক। আমাদের route/web.php-এর ভিতরে, আমাদের welcome routes এর পরে এটি অন্তর্ভুক্ত করুন:
Route::get('subscribe',function(){ return view('subscriber'); });
এর পরের কাজটি হল resources/views তে subscriber.blade.php নামে একটি view file তৈরি করা। এটি এমন কনটেন্ট হবে যা আমরা আমাদের সাবস্ক্রাইবারদের কাছে প্রদর্শন করব। subscriber.blade.php ফাইলে, নিম্নলিখিত কোডগুলো যোগ করুন:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Restricted Content</title> <!-- Styles --> <style> /* ! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com */*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}::after,::before{--tw-content:''}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:Figtree, sans-serif;font-feature-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*, ::before, ::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::-webkit-backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.relative{position:relative}.mx-auto{margin-left:auto;margin-right:auto}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.ml-4{margin-left:1rem}.mt-16{margin-top:4rem}.mt-6{margin-top:1.5rem}.mt-4{margin-top:1rem}.-mt-px{margin-top:-1px}.mr-1{margin-right:0.25rem}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.h-16{height:4rem}.h-7{height:1.75rem}.h-6{height:1.5rem}.h-5{height:1.25rem}.min-h-screen{min-height:100vh}.w-auto{width:auto}.w-16{width:4rem}.w-7{width:1.75rem}.w-6{width:1.5rem}.w-5{width:1.25rem}.max-w-7xl{max-width:80rem}.shrink-0{flex-shrink:0}.scale-100{--tw-scale-x:1;--tw-scale-y:1;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.grid-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr))}.items-center{align-items:center}.justify-center{justify-content:center}.gap-6{gap:1.5rem}.gap-4{gap:1rem}.self-center{align-self:center}.rounded-lg{border-radius:0.5rem}.rounded-full{border-radius:9999px}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242 / var(--tw-bg-opacity))}.bg-dots-darker{background-image:url("data:image/svg+xml,%3Csvg width='30' height='30' viewBox='0 0 30 30' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1.22676 0C1.91374 0 2.45351 0.539773 2.45351 1.22676C2.45351 1.91374 1.91374 2.45351 1.22676 2.45351C0.539773 2.45351 0 1.91374 0 1.22676C0 0.539773 0.539773 0 1.22676 0Z' fill='rgba(0,0,0,0.07)'/%3E%3C/svg%3E")}.from-gray-700\/50{--tw-gradient-from:rgb(55 65 81 / 0.5);--tw-gradient-to:rgb(55 65 81 / 0);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.via-transparent{--tw-gradient-to:rgb(0 0 0 / 0);--tw-gradient-stops:var(--tw-gradient-from), transparent, var(--tw-gradient-to)}.bg-center{background-position:center}.stroke-red-500{stroke:#ef4444}.stroke-gray-400{stroke:#9ca3af}.p-6{padding:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.text-center{text-align:center}.text-right{text-align:right}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-sm{font-size:0.875rem;line-height:1.25rem}.font-semibold{font-weight:600}.leading-relaxed{line-height:1.625}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99 / var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39 / var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128 / var(--tw-text-opacity))}.underline{-webkit-text-decoration-line:underline;text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.shadow-2xl{--tw-shadow:0 25px 50px -12px rgb(0 0 0 / 0.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.shadow-gray-500\/20{--tw-shadow-color:rgb(107 114 128 / 0.2);--tw-shadow:var(--tw-shadow-colored)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.selection\:bg-red-500 *::selection{--tw-bg-opacity:1;background-color:rgb(239 68 68 / var(--tw-bg-opacity))}.selection\:text-white *::selection{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity))}.selection\:bg-red-500::selection{--tw-bg-opacity:1;background-color:rgb(239 68 68 / var(--tw-bg-opacity))}.selection\:text-white::selection{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgb(17 24 39 / var(--tw-text-opacity))}.hover\:text-gray-700:hover{--tw-text-opacity:1;color:rgb(55 65 81 / var(--tw-text-opacity))}.focus\:rounded-sm:focus{border-radius:0.125rem}.focus\:outline:focus{outline-style:solid}.focus\:outline-2:focus{outline-width:2px}.focus\:outline-red-500:focus{outline-color:#ef4444}.group:hover .group-hover\:stroke-gray-600{stroke:#4b5563}@media (prefers-reduced-motion: no-preference){.motion-safe\:hover\:scale-\[1\.01\]:hover{--tw-scale-x:1.01;--tw-scale-y:1.01;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}}@media (prefers-color-scheme: dark){.dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39 / var(--tw-bg-opacity))}.dark\:bg-gray-800\/50{background-color:rgb(31 41 55 / 0.5)}.dark\:bg-red-800\/20{background-color:rgb(153 27 27 / 0.2)}.dark\:bg-dots-lighter{background-image:url("data:image/svg+xml,%3Csvg width='30' height='30' viewBox='0 0 30 30' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1.22676 0C1.91374 0 2.45351 0.539773 2.45351 1.22676C2.45351 1.91374 1.91374 2.45351 1.22676 2.45351C0.539773 2.45351 0 1.91374 0 1.22676C0 0.539773 0.539773 0 1.22676 0Z' fill='rgba(255,255,255,0.07)'/%3E%3C/svg%3E")}.dark\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left, var(--tw-gradient-stops))}.dark\:stroke-gray-600{stroke:#4b5563}.dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175 / var(--tw-text-opacity))}.dark\:text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity))}.dark\:shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.dark\:ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)}.dark\:ring-inset{--tw-ring-inset:inset}.dark\:ring-white\/5{--tw-ring-color:rgb(255 255 255 / 0.05)}.dark\:hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity))}.group:hover .dark\:group-hover\:stroke-gray-400{stroke:#9ca3af}}@media (min-width: 640px){.sm\:fixed{position:fixed}.sm\:top-0{top:0px}.sm\:right-0{right:0px}.sm\:ml-0{margin-left:0px}.sm\:flex{display:flex}.sm\:items-center{align-items:center}.sm\:justify-center{justify-content:center}.sm\:justify-between{justify-content:space-between}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr))}}@media (min-width: 1024px){.lg\:gap-8{gap:2rem}.lg\:p-8{padding:2rem}} </style> </head> <body class="antialiased"> <div class="relative sm:flex sm:justify-center sm:items-center min-h-screen bg-dots-darker bg-center bg-gray-100 dark:bg-dots-lighter dark:bg-gray-900 selection:bg-red-500 selection:text-white"> <h1 class="text-4xl font-semibold text-gray-900 dark:text-white">You are subscribed to this channel so you can view this content</h1> </div> </body> </html>
এর পরে, আমাদের এই পেজ টি সে সব ইউজারদের দ্বারা অ্যাক্সেস করা থেকে রেস্ট্রিক্টেড করতে হবে যারা সাবস্ক্রিপশন নেননি৷ এখন, এখানেই আমাদের Gate এর ব্যবহার আসে৷ এটি করার জন্য, আমরা প্রথমে আমাদের Gate কে App/providers/AuthServiceProvider.php-এর ভিতরে ডিফাইন করব, এবং এই AuthServiceProvider.php ফাইলের সবার উপরে অবস্থিত use \Support\Facades\Gate এই লাইনটির সামনের কমেন্ট টি মুছে ফেলুন ; অথবা এই লাইনটি টি অনুপস্থিত থাকলে এটি যোগ করুন, তারপর boot() মেথডের ভিতরে এটি যোগ করে Gate টি ডিফাইন করুন:
Gate::define('subscriber-only', function($user) { If ($user->subscribe ==1) { return true; } return false; });
এখানে, আমরা আমাদের Gate subscriber-only নাম দিয়েছি। এটি আমাদের ইউজার ডিটেলস পাবে।
পরবর্তী জিনিসটি হল আমাদের ইউজাররা যদি subscribe না করে থাকে তবে তাদের সামগ্রীতে অ্যাক্সেস থেকে সীমাবদ্ধ করা। আমাদের অ্যাকশন অথোরাইজ করতে হবে এবং allow() method ব্যবহার করতে হবে। এটি করার জন্য, আসুন routes/web.php- ফাইল এ ফিরে যাই এবং নিম্নলিখিতগুলির সাথে মিলিয়ে কোডটি পরিবর্তন করি:
Route::get('subscribe',function() { if (Gate::allows('subscriber-only', Auth::user())) { return view('subscriber'); } return redirect()->route('login'); });
উপরের কোডটি যাচাই করে যে authenticated ইউজার “subscriber” পেজটি অ্যাক্সেস করতে পারে কিনা। যদি তাই হয়, “subscriber” ভিউ প্রদর্শিত হয়।
সবশেষে, আমরা কনটেন্ট লিঙ্কটি শুধুমাত্র সাবস্ক্রাইবার এর কাছে দৃশ্যমান করব কারণ এটি “you are not authorized to view this” এর মতো কিছু দেখানোর পরিবর্তে এটিকে আরও দক্ষ করে তুলবে৷ Resource/views/welcome.blade.php-এ ফিরে যান আমাদের homepage লিঙ্কের ঠিক নীচে যেটা আগে লিখেছি , সেখানে নিচের কোডের মতো @can directive এর ভিতরে আমাদের লিঙ্কটি আবদ্ধ করে দিন।
@can('subscriber-only', Auth::user()) <a href="{{ url('/subscribe') }}" class="text-sm text-gray-700 dark:text-gray-500 underline">Subscribers</a> @endcan
উপরের কোডে, আমরা @can directive ব্যবহার করে ইউজারদের subscriber-only” authenticated আছে কিনা তা চেক করি। authenticated ইউজার subscriber-only অনুমতি না থাকলে আমাদের লিঙ্কটি প্রদর্শিত হবে না।
সব শেষ! এখন এখানে আমরা যা কিছু করেছি এবং আমরা যা ঘটতে চাই তার একটি সারসংক্ষেপ:
- আমরা এমন কনটেন্ট তৈরি করেছি যা আমরা শুধুমাত্র আমাদের subscription নেওয়া ইউজারদের দেখাতে চেয়েছিলাম।
- বর্তমানে authenticated ইউজারের পারমিশন আছে কিনা তা চেক করতে আমরা @can(‘sub-only’, Auth::user()) ব্যবহার করেছি।
- আমরা একটি লিঙ্ক তৈরি করেছি এবং এটি শুধুমাত্র সাবস্ক্রাইবারদের জন্য দৃশ্যমান করেছি। এটি gates ব্যবহার করে সম্ভব হয়েছে যা আমাদেরকে শুধুমাত্র অথোরাইজ ইউজারদের মধ্যে কনটেন্ট সীমাবদ্ধ করতে সাহায্য করেছে।
Test that the application works
এখন, আসুন আমাদের কোড রান করি এবং পরিবর্তনগুলি কাজ করে কিনা চেক করুন । প্রথমে, নীচের কমান্ডটি চালিয়ে অ্যাপ্লিকেশনটি শুরু করুন:
php artisan serve
তারপর, আপনার পছন্দের ব্রাউজারে http://localhost:8000 খুলুন এবং উপরের ডানদিকের কোণায় Login ক্লিক করুন। Login করার পর Laravel লিঙ্কে ক্লিক করুন। নিচের ভিডিও টি তে সব কিছু দেখানো হয়েছে :