복붙노트

[REDIS] Laravel 5.2 - 자신의 모든 장치에서 사용자를 로그 아웃하는 방법

REDIS

Laravel 5.2 - 자신의 모든 장치에서 사용자를 로그 아웃하는 방법

사용자가 특정 장치에서 로그 아웃 할 때 나는 그가 지금까지 로그인 한 모든 기기에서 로그 아웃합니다. 어떻게 Laravel에서 할.

나는 "predis / predis"를 설치하여 세션에서 사용자 ID를 유지하기 위해 레디 스를 사용했다 : "~ 1.0"

그리고 여기에서 로그인과 로그 아웃에 대한 내 컨트롤러는 다음과 같습니다

  public function postSignIn(Request $request)
    {       

       if (Auth::attempt(['email' => $request['email'], 'password' =>$request['password'] ]) ) {

       $redis = \Redis::connection();   
        $userId=Session::getId();
        $redis->sadd('users:sessions:'.$userId,Session::getId());
          return redirect()->route('main');

        }
        return redirect()->back();
    }



public function getLogout()
{
    $redis = Redis::connection();
    $userId=Session::getId();
    $userSessions = $redis->smembers('user:sessions:' . $userId);
    $currentSession = Session::getId();
    foreach ($userSessions as $sessionId) {
         if ($currentSession == $sessionId) {
      continue; 

            }
             $redis->srem('user:sessions:' . $userId, $sessionId);
            $redis->del('laravel:' . $sessionId);

        }
    Auth::logout();
    return redirect()->route('main');
}

그것은 성공적으로 로그인 얻을 것 또한 로그 아웃하지만 다른 장치에있는 모든 세션을 죽이지 않습니다.

어떻게 문제를 해결합니까?

해결법

  1. ==============================

    1.그래서 문제는, 레디 스에서 오타로 키 이름이었다 사용 된 기록 데이터에 대한 $ redis-> 사드 ( '사용자 : 세션 :'. $ userId를, 세션 :: getId ()); 여기서 키의 접두사 '사용자 : 세션'과 익숙해 데이터 $ redis-> 스렘 ( '사용자 : 세션 :'. $ userId를, $ sessionId가); 여기서 키의 접두사 '사용자 : 세션 :' 코드가 작동하지 않았고 DD ()는 빈 배열을 반환하는 이유 이잖아.

    그래서 문제는, 레디 스에서 오타로 키 이름이었다 사용 된 기록 데이터에 대한 $ redis-> 사드 ( '사용자 : 세션 :'. $ userId를, 세션 :: getId ()); 여기서 키의 접두사 '사용자 : 세션'과 익숙해 데이터 $ redis-> 스렘 ( '사용자 : 세션 :'. $ userId를, $ sessionId가); 여기서 키의 접두사 '사용자 : 세션 :' 코드가 작동하지 않았고 DD ()는 빈 배열을 반환하는 이유 이잖아.

    이 같은 정확한 코드 외모

    public function postSignIn(Request $request)
    {    
    
       if (Auth::attempt(['email' => $request['email'], 'password' =>$request['password'] ]) ) {
            $redis = \Redis::connection();   
            $userId=Session::getId();
            $redis->sadd('user:sessions:'.$userId,Session::getId());
            return redirect()->route('main');
        }
        return redirect()->back();
    }
    
    
    
    public function getLogout()
    {
        $redis = Redis::connection();
        $userId=Session::getId();
        $userSessions = $redis->smembers('user:sessions:' . $userId);
        $currentSession = Session::getId();
    
        foreach ($userSessions as $sessionId) {
             if ($currentSession == $sessionId) {
                 continue; 
             }
                $redis->srem('user:sessions:' . $userId, $sessionId);
                $redis->del('laravel:' . $sessionId);
            }
        Auth::logout();
        return redirect()->route('main');
    }
    
  2. ==============================

    2.나는 당신의 문제에 대한 제안 / 해결 방법을 가지고 :

    나는 당신의 문제에 대한 제안 / 해결 방법을 가지고 :

    당신은 문제를 해결하기 위해 다르게 생각해야하므로 데이터베이스에 저장되지 않은 세션과 함께 작업하는 ** 통증이다. 서로 다른 솔루션은 기록 사용자 ID 및 시간, 사용자가 로그 아웃하는 것입니다. 그런 다음 연결이 마지막 로그 아웃 날짜 이전의 연결을 끊 사용자입니다 않을 경우 미들웨어를 만들 수 있습니다. 그리고 그게 다야.

    내 프로토 타입과 같이 보일 것이다 : postSignIn 방법 라인에서 아래의 사용자를 기록합니다 (세션) 로그인 날짜 : 응용 프로그램 ( '요청') -> 세션 () -> 풋 ( 'login_date', 시간 ());

    getLogout 방법 라인에서 아래 전 세계적으로 사용자 로그 아웃 날짜를 기록합니다 : \ 캐시 :: 넣어 ( 'last_logout _'\ 인증 : ID (), 시간 ().);

    그리고 마지막 손질이 유사한 코드와 미들웨어 될 것이다 :

    if ($user = \Auth::user()) {
        $login_date       = app('request')->session()->get('login_date');
        $last_logout_date = \Cache::get('last_logout_' . $user->id, time() + 100);
        if ($login_date < $last_logout_date) {
            \Auth::logout();
            //redirect, error message...
        }
    }
    

    전체 코드 :

    행동 양식:

    public function postSignIn(Request $request)
    {
        if (Auth::attempt(['email' => $request['email'], 'password' => $request['password']])) {
            app('request')->session()->put('login_date', time());
    
            return redirect()->route('main');
        }
    
        return redirect()->back();
    }
    
    public function getLogout()
    {
        \Cache::put('last_logout_' . \Auth::id(), time());
        Auth::logout();
    
        return redirect()->route('main');
    }
    

    미들웨어 :

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class LogoutIfExpired
    {
        public function handle($request, Closure $next, $guard = null)
        {
            if ($user = \Auth::user()) {
                $login_date       = app('request')->session()->get('login_date');
                $last_logout_date = \Cache::get('last_logout_' . $user->id, time() + 100);
                if ($login_date < $last_logout_date) {
                    \Auth::logout();
    
                    return redirect()->route('main');
                }
            }
    
            return $next($request);
        }
    }
    
  3. from https://stackoverflow.com/questions/37405740/laravel-5-2-how-to-logout-a-user-from-all-of-his-devices by cc-by-sa and MIT license