51歳からのプログラミング　備忘　Laravel　自作 認証 モドキ

セキュリティーとかあまり関係ないような、個人運用のWEBサイトに、簡単な認証システム（モドキ）を実装したい！なんてニーズはないのだろうけれど、認証モドキを作ってみた。いつか使ってみようかな。フレームワークのを使えよ！って言われますね、たぶん。

#OverView
モドキなので、ほんとに簡単。バリデーションとか入れてません。
概要は下記

localhost:8000/でアクセスすると、認証済状態であればTOPページに、認証未済であればLoginページに遷移。ログインは、フォームで"123"を入力すればログイン完了！ログイン完了時にsessionとクッキーを設定して認証済状態にします。

sessionは`config.session`で、ブラウザを閉じるまでsessionを維持する状態としてます。認証済後は、topページ、secondページ、logoutページを移動できる。認証未済状態で直接top,second,logoutページにはアクセスできません。という感じでゴー！


#ファイル構成
Laravel 6.5.2

|ファイル名|説明|
|---------|---|
|web.php|ルートファイル|
|SampleController.php|コントローラ|
|MyAuth.php|ミドルウェア:ルート保護|
|login.blade.php|ログインファイル|
|top.blade.php||
|second.blade.php||
|logout.blade.php||


##web.php
```php:web.php
<?php

Route::get ('/','SampleController@confirmAuth');
Route::view('/login','login');
Route::get ('/sessStart','SampleController@sessStart');
Route::middleware(['MyAuth'])->group(function(){
  Route::view('/top','top');
  Route::view('/second','second');
  Route::view('/logout','logout');
  Route::get ('/deleteSess','SampleController@deleteSess');
});
```

##SampleController.php
```php:SampleController.php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cookie;

class SampleController extends Controller
{

  // session は mySession 、cookie は myCookieで設定
  // mySession == myCookie なら true を返す関数
  public static function checkCookie(){
    if( session()->has('mySession') && Cookie::has('myCookie') ){
      if( session('mySession') == Cookie::get('myCookie') ){
          return true;
      }
    }
    return false;
  }

  // checkCookie関数が true なら topページへ
  // false なら loginページに遷移
  public function confirmAuth(){
    if( self::checkCookie() ){ return view('top'); }
    return view('login');
  }

  // mySession と myCookie を設定して topページへ遷移
  public function sessStart(){
    $value = (string) rand();
    session()->put('mySession',$value);
    Cookie::queue('myCookie',$value);
    return view('top');
  }

  // logout 後 に、mySession と myCookie を削除
  public function deleteSess(){
    session()->forget('mySession');
    setcookie('myCookie','',time()-1);
    return redirect('/');
  }
}
```
##MyAuth.php
```php:MyAuth.php
// ミドルウェア
<?php

namespace App\Http\Middleware;

use Closure;
use App\Http\Controllers\Controller;
use App\Http\Controllers\SampleController;
use Illuminate\Http\Request;

class MyAuth
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */

    public function handle($request, Closure $next)
    {
      // SampleController の checkCookie関数を使ってチェック
      if(SampleController::checkCookie()){
        return $next($request);
      }
      return redirect('/login');
    }
}
```
Middleware　では　return view ではなく redirectにした。いろいろ調べてたらMidlewareはget送信するみたいな話が、どっかにあったな。
get送信ならRoute::viewで受けられると思うのだけれど、
Call to a member function setCookie() on null
とエラーを賜ります。なぜ？
return redirect でちゃんと動いたので、とりあえず。


##login.blade.php
```php:login.blade.php
{{-- jqueryを使えるようにする呪文です！ --}}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<script>
  $(function(){
    $('form').submit(function(e){
      e.preventDefault();

      // ログイン処理
      // 123が入力されていればログイン完了
      // ログイン完了なら、ログイン状態を維持する処理へ(SampleController@sessStart)

      if($('input').val() == "123"){
        location.href = "/sessStart";
      }
      return;
    });
  });
</script>

<form>
  <input type="text" value="123">
  <button>LOGIN</button>
</form>
```
##top.blade.php~logout.blade.php
```php:top.blade.php
<a href="/second">second</a> | <a href="/logout">logout</a>
<p>
top
```

```php:second.blade.php
<a href="/second">top</a> | <a href="/logout">logout</a>
<p>
second
```

```php:logout.blade.php
<a href="/second">top</a> | <a href="/second">second</a>
<p>
<a href="deleteSess">LOGOUT</a>
```

#メモ
Undefined variable: _SESSION
session_start()が正しく実行されていないときに出た！