Ukieweb

Diary

I write here what I learn

Develop Multiauth Using Laravel 5.4

Develop Multiauth Using Laravel 5.4

আলহামদুলিল্লাহ, প্রায় দুমাস পরে আবার আমার ডায়েরীতে লিখতে বসলাম। নতুন কি লিখবো কি লিখবো করে আর কিছুই লেখা হয়নি। তারপরে ব্যাক্তিগত কিছু ঝামেলা থাকায় আরো সময় বের করতে পারিনি। তাই আজকে একটু সময় নিয়ে লিখতে বসলাম। যাই হোক এবার আসি মূল প্রসঙ্গে, আমরা লারাভেলের Authentication নিয়ে সবাই কম বেশি কাজ করেছি। আর এটা জানি যে লারাভেলের Authentication পদ্ধতিটি খুবই সহজ ও কাষ্টমাইজেবল। আশা হারানোর কারন নেই, আমি এই সাধারন Authentication নিয়ে আজকে লিখতে বসিনি। আজকের বিষয় লারাভেলের Multiauth. তবে এটি কোনো থার্ডপার্টি প্যাকেজ ব্যবহার করে নয় বরং এটি লারাভেলের ডিফল্ট Authentication ব্যবহার করেই করবো।

Multiauth কি

Multiauth হলো এমন একটি প্রোসেস যেখানে একটি সিস্টেমে এখাধিক ধরনের ইউজার থাকবে একাধিক কাজের জন্য যাদের সমস্থ কাজের ধরনটিই ভিন্ন ও তারা সবাই ভিন্ন ভিন্ন ডাটা সোর্স থেকে তথ্য নিয়ে ইউজার লগইন করবে। অনেকেই Multiauth আর Authorization কে গুলিয়ে ফেলেন এক ভেবে। অথোরাইজেশন হলো সেই পদ্ধতি যেখানে একই ধরনের ইউজারের ভিন্ন ভিন্ন রোল হয় এবং সেই রোল অনুযায়ি তাদের কাজের ধরন ভিন্ন হয় কিন্তু Multiauth এ ইউজারের কাজের ধরন অনুযায়ি তাদের পৃথক করা হয় এবং তাদের তথ্যও ভিন্ন ডাটা সোর্সে রাখা হয়।

কখন Multiauth ব্যবহার করবেন

আমরা লারাভেলের সাধারন Authentication সবাই জানি যে এখানে সমস্থ User একটা নির্দিষ্ট টেবিলের তথ্য থেকে লগইন করে। কিন্তু একটা সিস্টেমের এমন একটা পরিস্থিতি আসতে পারে যে কিছু User এর তথ্য ও কার্যাবলী টোটাললি ভিন্ন তাই তাদেরকে ভিন্ন একটি স্থানে অর্থাৎ তাদের তথ্য ভিন্ন একটি টেবিলে রাখতে হয় ফলে ঐসকল User ঐ ভিন্ন টেবিল থেকে লগইন করবে। ব্যপারটা যতো সহজ মনে হচ্ছে লারাভেলে সেটা করা একেবারে সহজ নয়, হ্যা কাজটি খুব জটিলও নয় তবে খুব ভালো করে কনসেপ্টটি বুঝতে হবে। ধরুন আপনি একটা বড় অ্যাপ্লিকেশন বানাচ্ছেন, ধরুন সেটা ফেসবুকের মতো এক্ষেত্রে এর ইন্টার্নাল ডিজাইনটা কেমন হতে পারে? বুঝতে পারলেন না? আচ্ছে একটু পরিষ্কার করছি, ফেসবুকের যতো ব্যবহারকারী আছে এদের সবার একটা নির্দিষ্ট টেবিলে তথ্য আছে এবং এই ব্যবহারকারীগন যেমন আপনি ঠিক এই টেবিলের তথ্য থেকেই লগইন করেন। কারন এই সকল ব্যবহারকারীর ফেসবুকের রোল একই ধরনের অর্থাৎ এরা সবাই ফেসবুকে একই ধরনের কার্য সম্পাদন করে, যেমন (স্টাটাস পোষ্ট করা, মেসেস দেয়া, লাইক দেয়া, গ্রুপ তৈরী করা, পেজ তৈরী করা, গ্রুপে জয়েন করা ইত্যাদি)। যেহেতু এরা সবাই ফেসবুক ব্যবহারকারী তাই এরা কেউই ফেসবুকের কনফিডেনশিয়াল জায়গায় এক্সেসের অনুমোতি পায় না। কিন্তু যারা ফেসবুকে জব করেন, অর্থাৎ যারা ফেসবুকের এডমিনিস্ট্রেটিভ রোল প্লে করেন, যেমন (কোনো ইউজারের একাউন্টকে টেপমোরারি ব্লক করা, ইউজারের রিপোর্ট পর্যালোচনা করে সে অনুযায়ী ব্যবস্থা নেয়, কোন সার্ভিস এ্যাড করা বা বাতিল করা ইত্যাদি)। তো এগুলো একজন সাধারন ইউজার করতে পারবে না। তাই এই বিশেষ ধরনের ব্যবহারকারীদের জন্য অর্থাৎ যারা ফেসবুকের এডমিন রোল প্লে করবে ধরুন ফেসবুক সেই ব্যবহারকারীদের জন্য একটি ভিন্ন টেবিল তৈরী করলো admins নামে। আর এরা সবাই এই admin টেবিল থেকেই লগইন করবে। তাহলে চলুন দেখি কিভাবে users টেবিল ও admins টেবিল থেকে লারাভেলে পৃথকভাবে লগইন করা যায়।

আমরা এখানে Laravel 5.4 ভার্সন ব্যবহার করবো। তো চলুন শুরু করি।

চলুন মাইগ্রেশন তৈরী করি

প্রথমেই আমাদের usersadmins নামে দুটি মাইগ্রেশন তৈরী করবো, সেজন্য নিচের কমান্ড দুটো রান করাই।

php artisan make:migration create_users_table

যদিও লারাভেলে ডিফল্ট একটা users টেবিল তৈরীর মাইগ্রেশন ফাইল থাকে, এবার admins টেবিলের জন্য একটা মাইগ্রেশন লিখবো।

php artisan make:migration create_admins_table

এবার এই ফাইল দুটোতে নিচের মতো করে মাইগ্রেশন লিখুন

users টেবিল মাইগ্রেশন

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique()->nullable();
            $table->string('password', 60);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

admins টেবিল মাইগ্রেশন

class CreateAdminsTable extends Migration
{
    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique()->nullable();
            $table->string('password', 60);
            $table->string('role', 15);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

এবার মাইগ্রেশনটি নিচের কমান্ড দিয়ে রান করাই

php atisan migrate

ব্যস টেবিল দুটো মাইগ্রেট হয়ে গেলো।

এবার আমাদের দুটো Model তৈরী করতে হবে এই টেবিল দুটোর জন্য, তাহলে চলুন Model দুটো তৈরী করি

php artisan make:model User

লারাভেলে ডিফল্টভাই User মডেলটি থাকে তাই এটি তৈরী করার মূলত প্রয়োজন নেই

php artisan make:model Admin

এখানে খেয়াল রাখতে হবে যে যেসকল মডেল থেকে অথেনটিকেশন হবে সেগুলোকে Illuminate\Foundation\Auth\User::class ক্লাস থেকে এক্সটেন্ড করে নিতে হবে, আমি Admin মডেল এর জন্য করে দিলাম, আর User মডেলে এটি ডিফল্ট করাই থাকে

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    protected $table = 'admins';
}

তাহলে চলুন কনফিগার করে নেই

লারাভেলে অথেনটিকেশন কনফিগার করার জন্য আপনাকে config/auth.php ফাইলটিতে যেতে হবে। এরপরে খেয়াল করলে দেখবেন এখানে providers নামে একটা সেকশন আছে, আর এই সেকশনে users নামে একটি গার্ড ডিফল্ড দেয়া আছে নিচের মতো।

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => Tds\Models\User::class,
        ],
    ]

এবার আমরা এখানে নতুন একটি provider যুক্ত করবো admins নামে, তখন সেটি নিচের মতো হবে।

  'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Admin::class,
        ],
     ]

এখানে প্রতিটি Provider এর দুটি অপশন আছে, drivermodel নামে। driver মূলত লগইনের জন্য কোন প্রোসিডিউর ব্যবহার করবে সেটা আর মডেল হলো যে ডাটা সোর্স থেকে ইউজার লগইন করতে হবে সেটি। যেহেতু আমাদের সাধারন ইউজারের জন্য Provider তৈরী করাই আছে তাই আমরা শুধু Admin এর জন্য একটা নতুন Provider তৈরী করবো। আপনাদের মনে আছে আমরা একটা model তৈরী করেছিলাম admin এর জন্য? হ্যা admins provider এর model অপশনে আমরা সেই মডেলটিই ব্যবহার করেছি।

Multiauth এর জন্য আমাদের মূল কনফিগারেশন প্রায় শেষ, এবার আমাদের Guard তৈরী করতে হবে। config/auth.php ফাইলে খেয়াল করুন guards নামে আরেকটি সেকশন আছে যেখানে webapi নামে দুটি গার্ড লারাভেল কতৃকই দেয়া ছিলো।

 'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ]

এবার আমাদের শুধু Admin এর জন্য নতুন একটি গার্ড তৈরী করতে হবে যার মাধ্যমে লারাভেলের Auth এডমিনকে লগইন করাবে। তাই আমরা একটি guard তৈরী করবো admin নামে।

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],


        'admin' => [
            'driver' => 'session',
            'provider' =>'admins',
        ],
    ],

এখানে প্রতিটি guard এর দুটি অপশন driverproviderdriver মূলত লগইনের তথ্য কিভাবে জমা হবে সেটিকে বোঝানো হয়, আমরা এখানে admin এর তথ্য session জমা রাখবো। আর provider হিসেবে আমরা একটু আগে যে Provider টি তৈরী করেছি সেটিকে দিয়ে দিয়েছি।

শেষ হয়নি এবার আরেকটু বাকি আছে, সিস্টেমকে পাসওয়ার্ডের জন্য কিছু তথ্য দিতে হবে। লারাভেলের ডিফল্ট অথেনটিকেশনের জন্য users নামে একটি পাসওয়ার্ড তৈরী করা আছে Passwords সেকশনে।

'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60
        ],
    ]

আমরা Admin এর জন্য একটা পাসওয়ার্ড কনফিগ তৈরী করবো নিচের মতো

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60
        ],

        'admins' => [
            'provider' => 'admins',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

এখানে প্রতিটি password এর তিনটি অপশন provider, tableexpireprovider হলো এখানে Provider গুলো তৈরী করা আছে সেগুলো আর table হলো password reset তথ্য যে টেবিলে জমা থাকবে সেটি আর expire password এর expire time.

চলুন লগইন করি

আমাদের কনফিগারেশন শেষ এবার অথেনটিকেশন করার পালা। সাধারনতো আমরা লারাভেলে এভাবে লগইন করি

$credentials = ['email'=>'some@email.com', 'password'=>'secret_password'];
$login = Auth::attempt($credentials);
if ($login) {
    return redirect('/');
}

এই লগইন সিস্টেমে Auth::attempt($credentials) অর্থ হলো Auth::guard('web')->attempt($credentials) অর্থাৎ লারাভেলের ডিফল্ড গার্ড হলো web তাই আমরা যদি কোনো গার্ড অথেনটিকেশনের সময় সেট না করি তার অর্থ হলো লারাভেল তখন ডিফল্ট গার্ড নিয়ে কাজ করবে। config/auth.php ফাইলে defaults সেকশনে guard হিসেবে web কে দেয়া আছে। আর ডিফল্ট password দেয়া আছে users. এখানে users হলো পাসওয়ার্ড প্রোভাইডার।

তাহলে আমরা এডমিনকে কিভাবে লগইন করাবো? হুম অনেক কঠিক প্রশ্ন করে ফেলেছেন, আপনাকে ধন্যবাদ জনাব। প্রশ্নটি কঠিন হলেও এ কাজটি এখন একেবারেই সহজ, খুবই সহজ। এডমিন লগইন সেই সাধারন লগইনের মতোই শুধু আপনাকে লগইনের সময় guard টি বলে দিতে হবে।

$credentials = ['email'=>'some@email.com', 'password'=>'secret_password'];
$login = Auth::guard('admin')->attempt($credentials);
if ($login) {
    return redirect('/');
}

এবার দেখি লগইন ইউজারের তথ্য কিভাবে তুলে আনবো

সাধারনভাবে কোনো লগইন ইউজারের নাম বের করার জন্য আমরা এভাবে লিখি

echo Auth::user()->name;

যার অর্থ হলো

echo Auth::guard('web')->user()->name;

তাহলে এডমিনের জন্য এটা হবে এরকম

echo Auth::guard('admin')->user()->name;

আর আপনি যদি helper ফাংশন ব্যবহার করেন তবে সেটি নিচের মতো করে লিখবেন

echo auth('admin')->user()->id;

কি সহজ না? হুম সহজ, আর এর থেকে সহজ আর কিছু হতে পারে না। কোনো কিছু না বুঝলে কমেন্ট করতে পারেন, আর না হলে মুড়ি খেতে পারেন (অবশ্যই নিজের টাকায় কিনে)

ধন্যবাদ :)

2 Comments

24/05/2017

ধন্যবাদ ভাই :)

06/07/2017

Thanks a Ton

To make a comment you have to login