Laravelのログイン周りの事
Laravelでログイン周りを変更していたので、そのメモを残しておきます。
フロントエンドはReactでやっています。
Laravelのバージョンは7です。
- ログイン機能の追加
- ログイン後のリダイレクト先変更
- ルートの保護
- 名前でログイン
- ユーザ情報の取得
- ログアウトボタンの設置
- homeの編集
- 新規登録時にメール送信
- LaravelのAuth機能でリダイレクト先の変更
ログイン機能の追加
composer require laravel/ui php artisan ui react --auth npm install npm run dev php artisan migrate
これでログイン関係の機能とそのデーターベースができます・
ログイン後のリダイレクト先変更
デフォルトでは/homeになっていますが、ここを任意のページに変更します。
<!--場所はapp/Providers/RouteServiceProvider.phpです-->
public const HOME = '/home'; //ここを好きなURLに変えてください
これだけで変更できます。
ルートの保護
今のままでは/home以外にはログインしていなくてもアクセスできてしまうので、ログインしていないときは、ログインページに飛ばたいと思います
Route::get('/todo','TodoController@index');
ルートは適当に用意しておきます。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class TodoController extends Controller { public function __construct() { $this->middleware('auth'); } public function index() { return view('todo'); } }
コントローラのコンストラクターでmiddlewareメソッドを呼び出すだけです。
これでこのページはログインが必須になりました。
名前でログイン
デフォルトではメールアドレスとパスワードでログインする仕様になっているので名前とパスワードでログインするように変更する。
<!--場所はapp/Http/Controllers/Auth/LoginController--> <?php public function username(){ return 'name'; }
これを書き足すだけです。といってもAuthenticatesUsersをオーバーライドしてるだけなんですけどね。
ソースコード
https://github.com/laravel/framework/blob/5.8/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php
あとはログインフォームを書き直していきます。
<!--場所はresources/views/auth/login.blade.php--> <div class="form-group row"> <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label> <div class="col-md-6"> <input id="name" type="name" class="form-control @error('email') is-invalid @enderror" name="name" value="{{ old('email') }}" required autocomplete="name" autofocus> @error('name') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div>
emailだった所をnameに書き換えてあげるだけです。
英語じゃなくて日本語にしたい場合は下記URLを参考に
https://laraweb.net/tutorial/6949/
ユーザ情報の取得
今回はAPIを使って取得したいと思います。
<!--場所はroutes/api.php--> <?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::group(['middleware' => 'api'], function(){ Route::get('user', 'UserController@index'); });
ルートにはユーザの情報を取得するコントローラ指定しておきます。
次にコントローラを書いていきます。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; //追加 class UserController extends Controller { public function index(Request $request) { $user = Auth::user(); #これでログインユーザー情報を取得 return $user; } }
ここまで一旦、ログインした状態で/api/userにアクセスしてみてみ下さい。おそらく何も表示されません。
なので、以下のファイルを変えてください。
<!--場所はapp/Http/Kermel.php--> <?php protected $middleware = [ \App\Http\Middleware\TrustProxies::class, \Fruitcake\Cors\HandleCors::class, \App\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, \Illuminate\Session\Middleware\StartSession::class, //追加 ];
これで再び/api/userにアクセスするとユーザー情報が表示されます。
ついでにReactで表示する方法も書いておきます。
import React from 'react'; import ReactDOM from 'react-dom'; class Example extends React.Component{ constructor(props){ super(props); this.state={user:[]} } componentDidMount(){ axios .get('/api/user') .then(res => {this.setState({user: res.data});}) .catch(error => {console.log(error)}) console.log(this.state.user); } render(){ return( <div> <h1>ユーザー情報</h1> <p>{this.state.user.id}</p> <p>{this.state.user.name}</p> </div> ); } } export default Example; ReactDOM.render(<Example />, document.getElementById('example'));
これでユーザー情報が画面に表示されたと思います。
ログアウトボタンの設置
今度はログアウトボタンを設置していきます。
return( <div> <h1>ユーザー情報</h1> <p>{this.state.user.id}</p> <p>{this.state.user.name}</p> <a href="/api/logout">ログアウト</a> //追加 </div> );
aタグにこれから作るAPIをセットしておきます。
次にルーティングの設定です。
<?php Route::group(['middleware' => 'api'], function(){ Route::get('user', 'UserController@index'); Route::get('logout', 'UserController@logout'); //追加 });
コントローラに以下のコードを書き足して終わりです。
<?php public function logout(Request $request){ Auth::logout(); //これでログアウトできる return redirect('/'); }
ちなみにこのままだとAPIはログインしていないユーザーでもアクセスできるので、ルートの保護をしておくといいかもしれません。ここはあまり調べていないのでわかりません。
homeの編集
上記の画像の赤枠の編集は以下のコードを編集します。
<!--場所はresources/views/layouts/app.bladephp--> <!-- 26~28行 --> <a class="navbar-brand" href="{{ url('/todo') }}"> ユーザー情報 </a>
新規登録時にメール送信
イベントとリスナーを使って実装します。
ここはほとんど下記URLのままです。
https://reffect.co.jp/laravel/laravel-event-listener
メールの設定は下記記事から
nasubifx.hatenablog.com
一応コピペ用にコードを貼っておきます。
<?php //場所はapp/Http/Controllers/Auth/RegisterController.php use App\Events\UserRegistered; //追加 //省略 protected function create(array $data){ //app/User.phpで$fillableを使っている $user= User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), ]); //eventヘルパー関数 event(new UserRegistered($user)); return $user; }
デフォルトでは laravel規定のUserモデルを使うようになっています。
protected $table = 'users';
次にイベントの作成
まず、下記のコマンドでイベントを作成
php artisan make:event UserRegistered
中身を書いていきます。
<?php //場所はapp/Events/UserRegistered.php use App\User; //追加 class UserRegistered{ use Dispatchable, InteractsWithSockets, SerializesModels; public $user; public function __construct(User $user){ $this->user = $user; } /* 省略 */ }
次にリスナーを作って行きます。
手順はイベント作成と同じ。
まず、下記のコマンドでリスナーを作成
php artisan make:listener SendWelcomeEmail --event=UserRegistered
中身を書いていきます。
<?php //場所はapp/Listners/SendWelcomeEmail.php use App\Events\UserRegistered; //追加 use Mail; //追加 use App\Mail\WelcomeMail; //追加 class SendWelcomeEmail{ //省略 public function handle(UserRegistered $event){ Mail::to($event->user->email)->send(new WelcomeMail($event)); } }
イベントのuserプロパティにアクセスしています。
次にEventServiceProviderに作成したイベントとリスナーの情報を登録します。
<?php //場所はapp/Providers/EventServiceProvider.php use App\Events\UserRegistered; //追加 use App\Listeners\SendWelcomeEmail; //追加 class EventServiceProvider extends ServiceProvider{ protected $listen = [ UserRegistered::class => [ SendWelcomeEmail::class, ], ]; }
次にMailbleクラスを作って行きます。
php artisan make:mail WelcomeMail
中身を書いていきます。
<?php //省略 class WelcomeMail extends Mailable { use Queueable, SerializesModels; protected $name; public function __construct($event) { $this->name = $event->user->name; } public function build() { return $this->view('emails.welcome') ->subject('登録ありがとうございます') ->with(['name'=>$this->name]); } }
withメソッドでviewに登録時の名前をセットしています。
最後に本文の作成です
//場所はresouces/views/emails/welcome.blade.php <p>{{$name}}</p>
これで新規登録時にメールが届きます。
LaravelのAuth機能でリダイレクト先の変更
<?php //場所はapp/Http/Middleware/Authenticate.php namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; class Authenticate extends Middleware { /** * Get the path the user should be redirected to when they are not authenticated. * * @param \Illuminate\Http\Request $request * @return string|null */ protected function redirectTo($request) { if (! $request->expectsJson()) { return route('welcome'); //ここを変更 } } }
指定するルートには名前を付けておいて下さい。