質問編集履歴

2 文言修正

hasshy

hasshy score 101

2019/07/04 18:38  投稿

【Laravel】MultiAuthのサイトでバックドアを実装したい
バックドアという表現が正しいかわかりませんが、ログイン画面を経由せず、ログイン情報を使用せずにログインをさせる方法についてお伺いしたいです。 
管理画面が複数あるサイトを実装しているのですが、
管理画面間を代理でログイン出来るようなシステムを実装したいと考えています。
挙動自体はエラーではないので、エラーページも表示されず、laravelのエラーログにも残りません。
原因の探り方からでも構いませんのでご教示いただけないでしょうか?
## 実装したい事の概要
システム管理者とショップ管理者でそれぞれ管理画面の機能があります。 
システム管理者は基本的に増えませんが、ショップ管理者はシステム管理者の管理画面から追加します。 
システム管理者は基本的に増えませんが、ショップはシステム管理者の管理画面から追加します。 
運用上、ショップの作業をシステム管理者が代理で行いたい時もあります。
その時、システム管理者の機能に各ショップにログイン出来る仕組みを導入したいです。
### ページ構成
URLとlaravelのルートは以下です。 
本来は、パスワードリマインダーや管理画面の個々の機能もありますが省略します。 
url|route|概要
---|---|---
http://hoge.com/admin/login|admin.login|システム管理者のログイン
http://hoge.com/admin/shops/|admin.shop.index|登録されているスクール一覧。一覧の中に代理ログイン用のURLリンクが追加されます。 
http://hoge.com/admin/shops/{ショップのID}/proxy-login|admin.shops.proxy-login|指定したログインIDを元に代理でログインします。ログイン処理後は処理完了後ショップのホーム画面に遷移します。
http://hoge.com/shop/login|shop.login|本来のショップのログイン画面です。
http://hoge.com/shop/login|shop.logout|ショップのログアウト処理を行います。
http://hoge.com/shop/|shop.home|ログイン後に自動で遷移するショップのホーム画面です。
### 認証機能の設定
MultiAuthのサイトなので、gurdとproviderはそれぞれ設定しました。 
下記のように、adminとshopと言う名前で下記のような設定をしています。 
```
<?php
return [
   'defaults' => [
       'guard' => 'admin',
       'passwords' => 'admins',
   ],
   'guards' => [
       'web' => [
           'driver' => 'session',
           'provider' => 'users',
       ],
       'admin' => [
           'driver' => 'session',
           'provider' => 'admins'
       ],
       'shop' => [
           'driver' => 'session',
           'provider' => 'shops'
       ]
   ],
   'providers' => [
       'admins' => [
           'driver' => 'eloquent',
           'model' => App\Admin::class,
       ],
       'shops' => [
           'driver' => 'eloquent',
           'model' => App\Shop::class,
       ]
   ],
];
```
### セッションについて
管理画面毎にログイン時のセッションが衝突しないように、別のセッション名になるように設定しています。 
```php
use Illuminate\Support\Str;
$defaultSession = Str::slug(
   env('APP_NAME', 'laravel'), '_').'_session';
$conf = [
   (省略)
];
// 管理画面のセッション切り替え
$uri = isset($_SERVER['REQUEST_URI'])
   ? $_SERVER['REQUEST_URI']
   : '';
   
if(strpos($uri, '/admin/') === 0 || $uri === '/admin') {
   $conf['cookie'] = env(
       'admin_session',
       $defaultSession
   );
} elseif(strpos($uri, '/shop/') === 0 || $uri === '/shop') {
   $conf['cookie'] = env(
       'shop_session',
       $defaultSession
   );
}
```
## 代理ログインの処理
管理者のControllerに、ログイン画面から個別のショップにログインする処理を追加しています。 
ガードがadminからshopに変わりますので、ガードを新しく指定して、IDでログイン出来るように```loginUsingId```でログインさせます。 
### コントローラーの処理
ルート```admin.shops.proxy-login```で実行される処理が下記です。 
$shop_urlには、ログイン先が検索できる固有のIDが入ります。 
リダイレクト先のルート```shop.home ```では、ミドルウェアでschoolにログイン済みか検証します。 
もしログインされている事を確認できなければ、ログイン画面に遷移します。 
```php
<?php
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class ShopController extends Controller
{
   public function __construct()
   {
       $this->middleware('auth:admin');
   }
   
   public function proxyLogin($shop_url) {
   
       $shop = shop::where('shop_url', $shop_url);
   
       // 存在しないURLの場合は元の画面に戻す
       if(! $shop->exists() || $shop->count() > 1 ) {
           return back();
       }
   
       // ショップ管理画面のログイン
       Auth::guard('shop')->logout();
       Auth::guard('shop')->loginUsingId($shop->first()->id);
   
       // リダイレクト
       return redirect()->route('shop.home');
   }
}
```
## 実際の挙動
ショップのログイン画面にリダイレクトされます。 
そのため、ログイン処理は成功していない事はわかります。 
単純に、ショップの管理画面でログインすると正常にログイン出来ますので、ログイン側の処理に誤りがあるわけではなさそうです。
  • PHP

    38972 questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Laravel 5

    3340 questions

    Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

1 route更新

hasshy

hasshy score 101

2019/07/04 18:03  投稿

【Laravel】MultiAuthのサイトでバックドアを実装したい
バックドアという表現が正しいかわかりませんが、ログイン画面を経由せず、ログイン情報を使用せずにログインをさせる方法についてお伺いしたいです。 
管理画面が複数あるサイトを実装しているのですが、
管理画面間を代理でログイン出来るようなシステムを実装したいと考えています。
挙動自体はエラーではないので、エラーページも表示されず、laravelのエラーログにも残りません。
原因の探り方からでも構いませんのでご教示いただけないでしょうか?
## 実装したい事の概要
システム管理者とショップ管理者でそれぞれ管理画面の機能があります。 
システム管理者は基本的に増えませんが、ショップ管理者はシステム管理者の管理画面から追加します。 
運用上、ショップの作業をシステム管理者が代理で行いたい時もあります。
その時、システム管理者の機能に各ショップにログイン出来る仕組みを導入したいです。
### ページ構成
URLとlaravelのルートは以下です。 
本来は、パスワードリマインダーや管理画面の個々の機能もありますが省略します。 
url|route|概要
---|---|---
http://hoge.com/admin/login|admin.login|システム管理者のログイン
http://hoge.com/admin/shops/|admin.shop.index|登録されているスクール一覧。一覧の中に代理ログイン用のURLリンクが追加されます。 
http://hoge.com/admin/shops/{ショップのID}/proxy-login|admin.shops.proxy-login|指定したログインIDを元に代理でログインします。ログイン処理後は処理完了後ショップのホーム画面に遷移します。
http://hoge.com/shop/login|shop.login|本来のショップのログイン画面です。
http://hoge.com/shop/login|shop.logout|ショップのログアウト処理を行います。
http://hoge.com/shop/login|shop.home|ログイン後に自動で遷移するショップのホーム画面です。
http://hoge.com/shop/|shop.home|ログイン後に自動で遷移するショップのホーム画面です。
### 認証機能の設定
MultiAuthのサイトなので、gurdとproviderはそれぞれ設定しました。 
下記のように、adminとshopと言う名前で下記のような設定をしています。 
```
<?php
return [
   'defaults' => [
       'guard' => 'admin',
       'passwords' => 'admins',
   ],
   'guards' => [
       'web' => [
           'driver' => 'session',
           'provider' => 'users',
       ],
       'admin' => [
           'driver' => 'session',
           'provider' => 'admins'
       ],
       'shop' => [
           'driver' => 'session',
           'provider' => 'shops'
       ]
   ],
   'providers' => [
       'admins' => [
           'driver' => 'eloquent',
           'model' => App\Admin::class,
       ],
       'shops' => [
           'driver' => 'eloquent',
           'model' => App\Shop::class,
       ]
   ],
];
```
### セッションについて
管理画面毎にログイン時のセッションが衝突しないように、別のセッション名になるように設定しています。 
```php
use Illuminate\Support\Str;
$defaultSession = Str::slug(
   env('APP_NAME', 'laravel'), '_').'_session';
$conf = [
   (省略)
];
// 管理画面のセッション切り替え
$uri = isset($_SERVER['REQUEST_URI'])
   ? $_SERVER['REQUEST_URI']
   : '';
   
if(strpos($uri, '/admin/') === 0 || $uri === '/admin') {
   $conf['cookie'] = env(
       'admin_session',
       $defaultSession
   );
} elseif(strpos($uri, '/shop/') === 0 || $uri === '/shop') {
   $conf['cookie'] = env(
       'shop_session',
       $defaultSession
   );
}
```
## 代理ログインの処理
管理者のControllerに、ログイン画面から個別のショップにログインする処理を追加しています。 
ガードがadminからshopに変わりますので、ガードを新しく指定して、IDでログイン出来るように```loginUsingId```でログインさせます。 
### コントローラーの処理
ルート```admin.shops.proxy-login```で実行される処理が下記です。 
$shop_urlには、ログイン先が検索できる固有のIDが入ります。 
リダイレクト先のルート```shop.home ```では、ミドルウェアでschoolにログイン済みか検証します。 
もしログインされている事を確認できなければ、ログイン画面に遷移します。 
```php
<?php
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class ShopController extends Controller
{
   public function __construct()
   {
       $this->middleware('auth:admin');
   }
   
   public function proxyLogin($shop_url) {
   
       $shop = shop::where('shop_url', $shop_url);
   
       // 存在しないURLの場合は元の画面に戻す
       if(! $shop->exists() || $shop->count() > 1 ) {
           return back();
       }
   
       // ショップ管理画面のログイン
       Auth::guard('shop')->logout();
       Auth::guard('shop')->loginUsingId($shop->first()->id);
   
       // リダイレクト
       return redirect()->route('shop.home');
   }
}
```
## 実際の挙動
ショップのログイン画面にリダイレクトされます。 
そのため、ログイン処理は成功していない事はわかります。 
単純に、ショップの管理画面でログインすると正常にログイン出来ますので、ログイン側の処理に誤りがあるわけではなさそうです。
  • PHP

    38972 questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Laravel 5

    3340 questions

    Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る