กำหนดให้ Login ใช้งาน Session เดียวใน Yii Framework 2

คู่มือการเรียนรู้ Yii Framework 2 (Yii2)

บทเรียนดีๆ สำหรับผู้ที่ต้องการแบ่งปัน บทเรียนของคุณอาจมีค่าสำหรับอีกหลายๆ คน

beta version

กำหนดให้ Login ใช้งาน Session เดียวใน Yii Framework 2

มานพ กองอุ่น yii framework yii framework2 concurrent login session 400

ปัญหานี้เกิดขึ้นเมื่อสมาชิก (user) เดียว แต่สามารถ login เข้าระบบได้จากหลายๆ เครื่อง หลายๆ browser ทำให้ไม่สามารถควบคุมการใช้งานได้ เช่น user A เข้าเรียนหลักสูตร aaa ได้ จากนั้น user A เอา username และ password ไปแจกเพื่อนๆ 9 คน ซึ่งแต่ละคนก็จะสามารถ login เข้ามาเรียนหลักสูตร aaa ได้ ทำให้เกิดปัญหาและความเสียหายต่อผู้ให้บริการ

แนวทางการแก้ไขคือ เมื่อ user A login ให้ทำการลบ session อื่นๆ ที่กำลัง login ออกทั้งหมด และการแก้ไขในปัญหานี้สำหรับ Yii Framework จะใช้ Session ที่เก็บใน Database เป็นตัวจัดการนั่นเอง เริ่มกันเลย

สร้าง migration กันก่อนนะ

cmd

yii migrate/create create_session_table

จากนั้นแก้ไขไฟล์ที่สร้างขึ้นใน console/migrations/xxxx_xxxx_create_session_table.php ดังนี้

<?php

use yii\db\Migration;

/**
 * Handles the creation of table `session`.
 */
class m170927_114732_create_session_table extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('session', [
            'id' => $this->char(40)->notNull(),
            'expire' => $this->integer(),
            'data' => $this->binary(),
            'user_id' => $this->integer()
        ]);

        $this->addPrimaryKey('session_pk', 'session', 'id');
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        $this->dropTable('session');
    }
}

cmd ประมวลผล

yii migrate

จากนั้นทำการ generate model ด้วย gii generator เก็บไว้ใน common\models\Session.php

 

จากนั้นแก้ไขการตั้งค่า session ในส่วน components เพื่อให้เรียกใช้ session ใน database โดยแก้ไข frontend/config/main.php เพิ่มเติมส่วน session ใน components

//....
    'components' => [

        //...
        'session' => [
            'name' => 'EOFFICE',
            'class' => 'yii\web\DbSession',
            'sessionTable' => 'session',//ชื่อตารางเก็บ session
            'writeCallback' => function($session){
                
                return [
                    'user_id' => Yii::$app->user->id//กำหนด user_id
                ];
            }
        ],
        //...

    ]

จากนั้นปรับแต่ง actionLogin() ใน frontend/controllers/SiteController.php เพื่อให้ลบ Session จากเครื่อง/browser อื่นๆ ดังนี้

public function actionLogin()
    {
        //$this->layout = 'login';
        if (!Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            Session::deleteAll(['and', 'user_id = '.Yii::$app->user->getId(), "id != '".Yii::$app->session->id."'"]); //ส่วนที่เพิ่มเติม อย่าลืม use common\models\Session; ก่อนล่ะ
            return $this->goBack();
        } else {
            return $this->render('login', [
                'model' => $model,
            ]);
        }
    }

ทดสอบโดยการ login จากหลายๆ browser จากนั้น ลอง refresh แต่ละ browser จะเหลือ login concurrent เพียงที่ login ใน browser ตัวล่าสุดนั่นเอง

หมายเหตุ ต้องไม่เลือก remember me นะครับ

นี่เป็นเพียงวิธีการหนึ่งเท่านั้น หากเพื่อนๆ มีทางอื่นๆ ที่ดีกว่าช่วยแจ้งด้วยนะครับ

 


หากบทเรียนรู้มีความผิดพลาดประการใด หรือมีข้อเสนอแนะกรุณาแจ้ง contact@programmerthailand.com
มานพ กองอุ่น

มานพ กองอุ่น
admin

  • 2 เพื่อน
  • 9 ผู้ติดตาม
  • 758 โพสต์