2015-01-14 3 views
2

Возможно ли в Laravel 4 разрешить только один сеанс на пользователя за раз?Laravel: позволяет только один сеанс на пользователя за один раз

Например, если пользователь входит в систему и уже имеет другие сеансы, остальные сеансы отменены, предпочтительно с возможностью оповестить их почему?

Я использую драйвер сеанса Redis на Amazon ElastiCache, если это помогает.

+0

У вас может быть только один сеанс активным одновременно, вы можете поместить только разные данные одновременно на несколько сеансов. –

+1

Что вы имеете в виду? В Laravel 4 по умолчанию пользователь может входить в систему несколько раз с той же учетной записью на разных компьютерах, и все эти сеансы будут действительны. Я хочу сделать это так, как только они войдут в систему, все остальные сеансы, прикрепленные к их UserId, будут отменены. –

+0

Хорошо, теперь я понимаю, но для этого вам нужно будет запросить свой драйвер сеанса для всех сеансов, связанных с данным пользователем, и удалить их. Обычно я помещал это в базу данных и просто удалял другие, но в вашем случае я не знаю об этом решении. –

ответ

9

Да, я сделал аналогичный для моего проекта.

Итак, вам нужно добавить в свою модель пользователя еще один атрибут: last_sessid.

public function swapping($user) { 
    $new_sessid = \Session::getId(); //get new session_id after user sign in 
    $last_session = \Session::getHandler()->read($user->last_sessid); // retrive last session 

    if ($last_session) { 
     if (\Session::getHandler()->destroy($user->last_sessid)) { 
      // session was destroyed 
     } 
    } 

    $user->last_sessid = $new_sessid; 
    $user->save(); 
} 

Теперь, если у пользователя есть активный сеанс и знаки в другом браузере, первый сеанс будет удален.

P.S. Извините за мой плохой английский :)

+0

Разве это не просто регенерация сеанса? Если у него есть проблема, как в GMail, вы можете войти в систему на 5 машинах, и он хочет выйти из системы на других 4? Я думаю, что ваш код не решает его проблемы. –

+0

Например: вы вошли в chrome, вы открыли firefox и вошли в систему, а затем, когда вы вернетесь в chrome и попробуйте сделать что-то нужное только для входа в систему, ваш фильтр авторизации закроет исключение или перенаправит обратно с ошибкой, и т. д. И для меня этот код отлично работает 1 пользователь - 1 сеанс – xAoc

+0

Но он запрещает пользователю входить в систему одновременно в нескольких местах, а затем выбирать только для выхода из всех остальных. –

0

удалось решить так:

Массив SessionIds в Redis (на одного пользователя)

пример: user.sessions.[userid] [ .... ]

в входе перед фильтром:

foreach (json_decode($redis->get('user.sessions.$userId')) as $sesId) { 
    Session::getHandler()->destroy($sesId)); 
} 

// add session to redis 
$redis->set('user.sessions.$userId', json_encode([Session::getId()])); 

Таким образом, вы также можете создать числовое ограничение сеанса, просто уничтожить до NumActiveSessions - MaxSessions в Redis.

8

Для laravel 5.2 после выполнения команды make:auth вы можете создать метод: public function authenticated(Request $request,User $user) в AuthController.php и в этом методе вы сможете делать то, что хотите после входа в систему. Для одного сеанса для каждого пользователя мы добавим к AuthController на вершине:

use Illuminate\Http\Request; 
use Auth; 

И добавить функцию:

public function authenticated(Request $request,User $user){ 
    $previous_session = $user->session_id; 

    if ($previous_session) { 
     \Session::getHandler()->destroy($previous_session); 
    } 

    Auth::user()->session_id = \Session::getId(); 
    Auth::user()->save(); 
    return redirect()->intended($this->redirectPath()); 
} 

Не забудьте добавить миграции для изменения вашей таблицы пользователей с session_id колонки.