Skip to content

Commit 3497c54

Browse files
authored
Merge pull request #2222 from opensource-workshop/forceLogout
[認証]全ユーザの強制ログアウト機能を作りました。
2 parents d06834c + 56652d1 commit 3497c54

File tree

7 files changed

+179
-2
lines changed

7 files changed

+179
-2
lines changed

app/Http/Controllers/Auth/LoginController.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,18 @@ public function login(Request $request)
9595

9696
try {
9797
// 以下はもともとのAuthenticatesUsers@login 処理
98-
return $this->laravelLogin($request);
98+
// return $this->laravelLogin($request);
99+
100+
// ログインが成功したら、一旦戻り値を保持しておき、強制ログアウトフラグをクリアする。
101+
$login_return = $this->laravelLogin($request);
102+
if (Auth::check() && Auth::user()->is_force_logout) {
103+
// 強制ログアウトフラグを処理済みの 0 に戻す
104+
$user = Auth::user();
105+
$user->is_force_logout = 0;
106+
$user->save();
107+
}
108+
return $login_return;
109+
99110
} catch (ValidationException $e) {
100111
// ログインエラーの場合、NetCommons2 からの移行ユーザとして再度認証する。
101112
$redirectNc2 = $this->authNetCommons2Password($request);
@@ -141,7 +152,18 @@ public function login(Request $request)
141152
// 通常ログインも使用する
142153
try {
143154
// 以下はもともとのAuthenticatesUsers@login 処理
144-
return $this->laravelLogin($request);
155+
// return $this->laravelLogin($request);
156+
157+
// ログインが成功したら、一旦戻り値を保持しておき、強制ログアウトフラグをクリアする。
158+
$login_return = $this->laravelLogin($request);
159+
if (Auth::check() && Auth::user()->is_force_logout) {
160+
// 強制ログアウトフラグを処理済みの 0 に戻す
161+
$user = Auth::user();
162+
$user->is_force_logout = 0;
163+
$user->save();
164+
}
165+
return $login_return;
166+
145167
} catch (ValidationException $e) {
146168
// ログインエラーの場合、NetCommons2 からの移行ユーザとして再度認証する。
147169
$redirectNc2 = $this->authNetCommons2Password($request);

app/Http/Kernel.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class Kernel extends HttpKernel
3333
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
3434
\Illuminate\Session\Middleware\StartSession::class,
3535
// \Illuminate\Session\Middleware\AuthenticateSession::class,
36+
\App\Http\Middleware\ForceLogoutMiddleware::class,
3637
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
3738
\App\Http\Middleware\VerifyCsrfToken::class,
3839
\Illuminate\Routing\Middleware\SubstituteBindings::class,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace App\Http\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Support\Facades\Auth;
8+
9+
class ForceLogoutMiddleware
10+
{
11+
/**
12+
* Handle an incoming request.
13+
*
14+
* @param \Illuminate\Http\Request $request
15+
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
16+
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
17+
*/
18+
public function handle(Request $request, Closure $next)
19+
{
20+
if (Auth::check() && Auth::user()->is_force_logout) {
21+
// 強制ログアウトフラグを処理済みの 0 に戻す
22+
$user = Auth::user();
23+
$user->is_force_logout = 0;
24+
$user->save();
25+
26+
Auth::logout();
27+
$request->session()->invalidate();
28+
$request->session()->regenerateToken();
29+
return redirect('/login')->with('error', '強制的にログアウトされました。');
30+
}
31+
return $next($request);
32+
}
33+
}

app/Plugins/Manage/UserManage/UserManage.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Illuminate\Support\Arr;
3434
use Illuminate\Support\Facades\Auth;
3535
use Illuminate\Support\Facades\Hash;
36+
use Illuminate\Support\Facades\Log;
3637
use Illuminate\Support\Facades\Storage;
3738
use Illuminate\Support\Facades\Validator;
3839
use Illuminate\Support\Facades\DB;
@@ -84,6 +85,8 @@ public function declareRole()
8485
$role_check_table["loginHistory"] = ['admin_user'];
8586
$role_check_table["mail"] = ['admin_user'];
8687
$role_check_table["mailSend"] = ['admin_user'];
88+
$role_check_table["forceLogout"] = ['admin_user'];
89+
$role_check_table["forceLogoutSubmit"] = ['admin_user'];
8790
// 項目セット
8891
$role_check_table["columnSets"] = ['admin_site'];
8992
$role_check_table["registColumnSet"] = ['admin_site'];
@@ -3290,4 +3293,44 @@ public function deleteSection($request, $id)
32903293
// 編集画面を呼び出す
32913294
return redirect("/manage/user/editColumnDetail/" . $request->column_id)->with('flash_message', $message);
32923295
}
3296+
3297+
/**
3298+
* 強制ログアウト
3299+
*
3300+
* @method_title 強制ログアウト
3301+
* @method_desc 自分以外の全ユーザを強制ログアウトさせます。
3302+
* @method_detail ログイン済みのユーザは次回の画面遷移時にログアウトさせられ、ログイン画面に誘導されます。
3303+
*/
3304+
public function forceLogout($request, $id = null)
3305+
{
3306+
// 画面の表示
3307+
return view('plugins.manage.user.force_logout', [
3308+
"function" => __FUNCTION__,
3309+
]);
3310+
}
3311+
3312+
/**
3313+
* 強制ログアウトのデータ更新処理
3314+
*
3315+
* 自分以外のusersテーブルのis_force_logoutを1に更新する。
3316+
* 各ユーザは次のアクションでmiddlewareが動作し、ログインしていてis_force_logoutが 1 の場合は強制ログアウトする。
3317+
*/
3318+
public function forceLogoutSubmit($request, $id = null)
3319+
{
3320+
// ユーザデータの更新(自分以外かつadmin_userロールを持たないユーザーのみ)
3321+
User::where('id', '!=', Auth::user()->id)
3322+
->whereNotExists(function ($query) {
3323+
$query->select('id')
3324+
->from('users_roles')
3325+
->whereRaw('users_roles.users_id = users.id')
3326+
->where('role_name', 'admin_user')
3327+
->where('role_value', 1);
3328+
})
3329+
->update(['is_force_logout' => 1]);
3330+
3331+
Log::info('Force logout registered by admin user ID: ' . Auth::user()->id);
3332+
3333+
// 更新後は強制ログアウトを呼ぶ。
3334+
return redirect()->back()->with('flash_message', '強制ログアウトを設定しました。<br />対象ユーザは、次回の画面操作でログアウトされ、ログイン画面に誘導されます。');
3335+
}
32933336
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class AddForceLogoutToUsersTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('users', function (Blueprint $table) {
17+
$table->boolean('is_force_logout')->default(0)->comment('強制ログアウトフラグ')->after('add_token_created_at');
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('users', function (Blueprint $table) {
29+
$table->dropColumn('is_force_logout');
30+
});
31+
}
32+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{{--
2+
* 強制ログアウト画面テンプレート
3+
--}}
4+
5+
{{-- 管理画面ベース画面 --}}
6+
@extends('plugins.manage.manage')
7+
8+
{{-- 管理画面メイン部分のコンテンツ section:manage_content で作ること --}}
9+
@section('manage_content')
10+
11+
<div class="card">
12+
<div class="card-header p-0">
13+
{{-- 機能選択タブ --}}
14+
@include('plugins.manage.user.user_manage_tab')
15+
</div>
16+
<div class="card-body">
17+
18+
{{-- 登録後メッセージ表示 --}}
19+
@include('plugins.common.flash_message')
20+
21+
<div class="card border-danger">
22+
<div class="card-body">
23+
<span class="text-danger">強制ログアウトを設定します。<br />全ユーザ、次回の画面操作でログアウトされ、ログイン画面に誘導されます。<br />ただし、自分とユーザ管理者権限を持つユーザはログアウトが設定されません。</span>
24+
25+
<div class="text-center mt-3">
26+
{{-- 強制ログアウトボタン --}}
27+
<form action="{{url('/manage/user/forceLogoutSubmit')}}" method="POST">
28+
{{csrf_field()}}
29+
<button type="submit" class="btn btn-danger" onclick="javascript:return confirm('強制ログアウトを設定します。\nよろしいですか?')"><i class="fas fa-check"></i> 強制ログアウトを設定する。</button>
30+
</form>
31+
</div>
32+
33+
</div>
34+
</div>
35+
36+
</div>
37+
38+
@endsection

resources/views/plugins/manage/user/user_manage_tab.blade.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@
106106
@endif
107107
</li>
108108

109+
<li role="presentation" class="nav-item">
110+
@if ($function == "forceLogout")
111+
<span class="nav-link"><span class="active">強制ログアウト</span></span>
112+
@else
113+
<a href="{{url('/manage/user/forceLogout')}}" class="nav-link">強制ログアウト</a></li>
114+
@endif
115+
</li>
116+
109117
</ul>
110118
</div>
111119
</nav>

0 commit comments

Comments
 (0)