Laravelでウィザード形式のユーザー登録にSNS認証も混ぜて実装してみた

2021.01.18

見出し画像

今回は前回書いた記事の内容と少し変えてSNSログインをウィザード形式で実装してみよう!ということです。

GoogleとFacebookです。基本的にgoogleで進めていきますが、facebookと若干違う処理をしているところがあるので少し書きます。

目次

  1. 前提
  2. Googleでプロジェクトを作成、必要なものを取得
  3. ルーティング,コントローラーにアクション設定
  4. コントローラーのアクション
  5. コントローラーで取得保存
  6. facebookの時に違う部分(emailがない時の対応)
  7. bladeでsessionの情報を表示
  8. 学んだとこ
  9. まとめ

前提

以前の記事のように普通のウィザード形式の実装は住んでいるとして話を進めます。あとはgoogle側の設定については参考記事を参考にしてください。

基本的な流れ

Googleでプロジェクトを作成、必要なものを取得

ルーティング,コントローラーにアクション設定

コントローラーのアクション

ウィザードへの紐付け

facebookの時に違う部分(emailがない時がある)

と言った流れで実装していきます。

Googleでプロジェクトを作成、必要なものを取得

今回はウィザード形式部分について説明するので省略しますw。記事を参考にプロジェクトを作成、apiの取得envに書き込みまで行なってくだい。socialiteとかも。config/services.phpにも必要かと。

参考記事

ルーティング,コントローラーにアクション設定

まずはルーティングの設定をしていきます。シンプルです。グーグル側に飛んで行くリンクと帰ってきた時のリンクを設定します。

Route::get('/login/google', 'Auth\LoginController@redirectToGoogle')->name('google_login_before');
Route::get('/login/google/callback', 'Auth\LoginController@GoogleCallback')->name('google_login_after');

コントローラーにアクションを設定します。処理はまだ書きません。

use Socialite;
use App\User;
use Auth;
use Carbon\Carbon;
use Session;

    public function redirectToGoogle()
   {
   
   }
   
    public function GoogleCallback()
    {
    
    }

view側にクリックする為のボタンを設置します。

<a href="{{ route('google_login_before') }}" class="btn btn-secondary mr-2" role="button">
  Google Login
</a>

ボタンをクリックすると先ほど設定したアクションに行く感じです。中の処理を書いていきます。

コントローラーのアクション

use Socialite;
use App\User;
use Auth;
use Carbon\Carbon;
use Session;
  
   public function redirectToGoogle()
   {
       // Google へのリダイレクト
       return Socialite::driver('google')->redirect();
   }
   
   
   public function GoogleCallback()
   {
       // Google 認証後の処理
       // statelessについてhttps://qiita.com/hikarizm/items/44c1e9ff34726c9260d3
   #1  $gUser = Socialite::driver('google')->stateless()->user();
   #2  $check_user = User::where(['email' => $gUser->getEmail()])->first();
       if($check_user) {
           Auth::login($check_user);
           return redirect()->route('home');
       } else {
           $user = new User();
           $now_time = Carbon::now('Asia/Tokyo');
           $user->name = $gUser->getName();
           $user->email = $gUser->getEmail();
   #3      $user->email_verified_at = $now_time;
           $user->password = \Hash::make('password');
           // セッションに値を入れてaddressに飛ばしている
   #4      Session::put('user', $user);
           return view('auth.address')->with('say', 'ユーザーは入力完了です!次は住所を入力してください!');
       }

   }

#1, グーグルユーザーの情報を取得しています。statelessは簡単にいうと”nullの情報があった時の為”といった感じです。

#2, 取得したユーザーのアカウントが既に存在しているかをemailを使ってチェックしています。存在していたらそのままログインです。

#3, 認証メールが送られてこないようにしています。sns認証しているので確認メールはしつこいかなと感じたのでwつけたい方は削除してもらえれば大丈夫です。

#4, セッションの中にユーザーの情報を入れて住所登録画面に遷移するようにしています。入れる情報は$user->nameとかで入れてください。

sessionに必要な情報は入っているのであとは前回記事通りコントローラーでsaveすればオーケーです。

コントローラーで取得保存

前回の記事とほぼ同じです。

       $all = Session::all();
       $user = new User();
       $user->name = $all['user']->name;
       $user->email = $all['user']->email;
       $user->password = $all['user']->password;
       if($all['user']->email_verified_at){
           $user->email_verified_at = $all['user']->email_verified_at;
           $user->save();
       }
       $user->save();
       
       ...省略
       
       Auth::login($user);
       // 認証されていない場合は、認証メールを送る
       if(!isset($user->email_verified_at)) {
           $user->sendEmailVerificationNotification();
       }
       return redirect()->route('home')->with('say', '登録が完了しました!');

facebookの時に違う部分(emailがない時の対応)

facebookの方もやっていて気づいたのがfacebookから来る情報の中でemailがない時があるって事。なのでemailを記入させるような処理しています。

変更部分は

       $fUser = Socialite::driver('facebook')->stateless()->user();    
       $check_user = User::where(['email' => $fUser->getEmail()])->first();
       if($check_user) {
           Auth::login($check_user);
           return redirect()->route('home');
   #1  } elseif($fUser->getEmail() === null) {
           // facebookはユーザーがemailを持っていない場合があるので、その場合はauth.registerに飛ばしてemailを入力させる
           $user = new User();
           $user->name = $fUser->getName();
           Session::put('user', $user);
           return view('auth.register')->with('say', 'ユーザーのemailを入力してください!');
       } else {
           $user = new User();
           $now_time = Carbon::now('Asia/Tokyo');
           $user->name = $fUser->getName();
           $user->email = $fUser->getEmail();
           $user->email_verified_at = $now_time;
           $user->password = \Hash::make('password');
           // セッションに値を入れてaddressに飛ばしている
           Session::put('user', $user);
           return view('auth.address')->with('say', 'ユーザーは入力完了です!次は住所を入力してください!');
       }

#1, emailが取得出来ない場合はreturnで返すviewを変更しています。

sessionに情報を入れた状態でview画面に行くので、nameは取得しているのでbladeで表示していきます。

bladeでsessionの情報を表示

名前を入力する部分でsessionの中に情報が入っている場合のinputを書きます。value=”{{ Session::get(‘user.name’) }}”で取得した情報を表示させることができます。

他の部分でも同じ流れで組み立てていけるかと思います。

@if(session('user'))
  <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ Session::get('user.name') }}" autocomplete="name" autofocus>
@else
  <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" autocomplete="name" autofocus>
@endif

学んだとこ

statelessメソッドでnullが返ってきた時に対応する。

まとめ

使っている技術としては特に新しいことは取り入れていないので、前回の記事も確認しながらだとしっかりと実装できるかなと思います。

今回はそんな感じで

以上!