2015-08-11 29 views
5

Tôi muốn đăng xuất một phiên người dùng đã đăng nhập vào một trình duyệt/môi trường khác từ phiên hiện tại của cùng một người dùng. Một tính năng tương tự như thế này - https://www.facebook.com/settings?tab=security&section=sessions&view.Yii2 từ xa đăng xuất một phiên người dùng từ phiên hiện tại của người dùng

Yii2 là khung công tác phụ trợ được sử dụng. Sử dụng redis để quản lý phiên - yii2-redis. Tôi cũng lưu các id phiên được lưu trong cơ sở dữ liệu.

Tôi đi theo bài viết này - http://www.codeinphp.com/general/php-code-snippets/remotely-destroy-different-session-php-forced-user-signout/

Nhưng không có bất kỳ thành công.

session_id($old_session_id); 
session_start(); // This line throws error. 
session_destroy(); 

Xóa khóa bằng màu đỏ bằng cách sử dụng \Yii::$app->session->destroySession($oldSessionId) không đăng xuất.

Thay đổi id phiên thành cũ và sau đó hủy phiên cũng không hoạt động.

$currentSessionId = \Yii::$app->session->getId(); 
\Yii::$app->session->setId($oldSessionId); 
\Yii::$app->getSession()->destroy(); 
\Yii::$app->session->setId($currentSessionId); 

Nếu có ai thành công trong việc triển khai thành công, vui lòng chia sẻ giải pháp của bạn. Ngoài ra nếu có bất kỳ tài liệu nào liên quan đến việc này có thể giúp đỡ, vui lòng cung cấp.

+0

Nhờ @ Ngô Văn Thảo và @Nate cho câu trả lời của họ. Đây là cách tiếp cận mà tôi theo sau khi lấy đầu vào từ câu trả lời của họ. Đặt 'enableAutoLogin' thành false. Tạo bảng 'phiên' (user_id, session_id) cùng với các thuộc tính khác liên quan đến thiết bị, trình duyệt. Trong phương thức 'afterLogin', thêm user_id và session_id vào bảng 'session'.Để đăng xuất một phiên từ xa, hãy hủy phiên sử dụng -Yii :: $ app-> session-> destroySession (sessionId) và thay đổi auth_key của người dùng. Lưu ý: Điều này không hoạt động đối với thành phần Phiên mặc định. Hoạt động tốt với 'yii \ redis \ Session' – Gowrav

Trả lời

3

Đầu tiên, session_start() phải được gọi trước khi session_id() và chỉ cần gọi một lần duy nhất

if (session_status() == PHP_SESSION_NONE) { 
    session_start(); 
} 
session_id($old_session_id); 
session_destroy(); 

Nhưng chỉ cần loại bỏ phiên, đó là chưa đủ nếu bạn cho phép người dùng tự động đăng nhập vì trình duyệt sẽ tự động đăng nhập bằng cách sử dụng các tập tin cookie. Để giải quyết, bạn phải thay đổi người dùng AuthKey - Yii2 sử dụng AuthKey để xác thực đăng nhập tự động của người dùng. Theo mặc định, mỗi người dùng chỉ có một AuthKey trong bảng người dùng để khi bạn thay đổi AuthKey đăng xuất của người dùng ở mọi nơi. Vì vậy, chúng ta phải tùy chỉnh. Tạo cho mỗi phiên người dùng một AuthKey, được lưu trữ ở đâu đó không có trong bảng người dùng. Làm điều đó dễ dàng: mở rộng yii \ web \ Ghi đè lớp người dùng afterLogin để tạo AuthKey cho mỗi phiên đăng nhập. ghi đè chức năng validateAuthKey để xác thực đăng nhập tự động sử dụng tùy chỉnh AuthKey của chúng tôi. Bây giờ khi bạn muốn giết bất kỳ phiên người dùng nào: hãy hủy id phiên PHP và AuthKey phiên đó sẽ bị đăng xuất ngay lập tức. Tôi đã sử dụng giải pháp này cho các dự án của mình và nó hoạt động tốt.

+0

Không hoạt động cho tôi. Tôi đã đặt autoLogin thành true. Tôi sử dụng tên người dùng + đăng nhập dựa trên mật khẩu tương tự như https://github.com/yiisoft/yii2-app-basic/blob/master/models/LoginForm.php. Thay đổi auth_key chỉ cập nhật cookie _identity và không đăng xuất phiên. Bạn có thể vui lòng chia sẻ một số mã mẫu của việc triển khai của bạn không. Ngoài ra loại đăng nhập bạn sử dụng. – Gowrav

+0

bạn phải hủy cả phiên AuthKey và PHP giống như cách bạn đã thực hiện –

+0

thay đổi hoặc xóa 'AuthKey' chỉ ngăn tự động đăng nhập, giết phiên php sẽ giết phiên người dùng ngay lập tức. –

1

Dựa trên câu trả lời của Ngô, tôi đã tìm ra phương pháp hoạt động tốt và dễ thiết lập hơn.

1) Thêm trường "last_session_id" vào bảng người dùng của bạn.

2) Thêm sau để điều khiển chính của bạn:

public function afterAction($action, $result) 
{ 
    $result = parent::afterAction($action, $result); 

    if(Yii::$app->user->id) 
    { 
     //update the user table with last_session_id 
     $user = User::find()->where(['id' => Yii::$app->user->id])->one(); 
     $user->last_session_id = Yii::$app->session->id; 
     $user->save(false); 
    } 

    return $result; 
} 

3) Thay đổi trang web/action login để sau:

public function actionLogin() 
{ 
    if (!\Yii::$app->user->isGuest) { 
     return $this->goHome(); 
    } 

    $model = new LoginForm(); 
    if ($model->load(Yii::$app->request->post()) && $model->login()) { 

     //delete previous session ID and change auth key 
     Yii::$app->session->destroySession(Yii::$app->user->identity->last_session_id); 
     $u = \common\models\User::find()->where(['id' => Yii::$app->user->id])->one(); 
     $u->auth_key = Yii::$app->security->generateRandomString(); 
     $u->save(false); 
     return $this->goBack(); 
    } else { 
     return $this->render('/site/login', [ 
      'model' => $model, 
     ]); 
    } 
} 
Các vấn đề liên quan