【Laravel】GoogleのOAuth認証でログイン機能を実装する(PHP)
LaravelのSocialiteに感動したのでメモ。
【やりたいこと】
GoogleのOAuthAPIを用いてログイン機能を実装する
※ログインのみ、GoogleのAPIを用いて判定、
ユーザ情報はGoogle APIから取得する。
また、今回はuserの新規作成は割愛します。ログインのみ。
emailで管理ユーザか否か判定します。
※必要な方は、ログイン時にユーザがいなければcreateしてください。
【環境】
Laravel5.5
PHP7.2
Google API
【前提】
php artisan make:auth 実施済(なければ叩いてください)
Usersテーブル(もしくはauthに対応したテーブル)が存在する
DBは接続済み
ログインできるGoogleアカウントがある
やってみます。
Laravelは公式で、Google、Facebook、Twitterなど
様々なソーシャル認証を使用できるパッケージを持っています。(神)
Google側
OAuth情報を取得・設定
この辺りは、Qiitaや記事がたくさんありますので割愛。
Google developerコンソールで、プロジェクト作成します。
Google OAuth 2.0 認証を使ったログインの実装 - Qiita
GoogleのOAuth2.0を使ってプロフィールを取得【PHP】 - FaMirror Project
・クライアントID(自動発行)
・クライアントシークレット(自動発行)
・リダイレクト先 (自分で設定)Ex.https://samplesample.jp/login/google/callback
が今後必要になります。
※redirectは、ログイン後にアクセスするURLになります。ご自身で設定ください。
※使用できるURLに制限があります!
.comや.jpなど、パブリックドメインのみ使用可能。(プライベートはlocalhostのみ)
これでかなりハマりました。。。
apacheいじって、.jpに変更したらgoogleが許してくれました。
もしgoogleから not foundなどのエラーが吐かれた場合、ここに問題ある可能性あります。
APIの有効化
Google のdeveloperコンソール、左側メニューのライブラリを選択。
Google Cloud Platform
・Google + API
・Google Drive API
・Contacts API
この3つが必要になりますので、全て有効にしてください。
こういうものですね。
これで、Google側の設定は完了です。
Laravelの設定
Socialiteパッケージをインストール
まずは、composerでinstallしましょう。
composer require laravel/socialite
Configの設定変更
コントローラでSocialiteを使用するため、
providerとaliasに登録しておきます。
config/app.php
<?php Laravel\Socialite\SocialiteServiceProvider::class, /.../ 'Socialite' => Laravel\Socialite\Facades\Socialite::class,
config/service.php
<?php 'google' => [ 'client_id' => env('GOOGLE_CLIENT_ID'), 'client_secret' => env('GOOGLE_CLIENT_SECRET'), 'redirect' => env('APP_URL').'/login/google/callback', ],
シークレットなど隠すために、.envファイルで設定します。
.envファイル
<?php APP_URL=(自分のwebアプリURL(上の方に既存)) ... GOOGLE_CLIENT_ID=(自分のクライアントID|新規作成) GOOGLE_CLIENT_SECRET=(自分のクライアントシークレット|新規作成)
以上で設定が完了しました。
Controller/Model/Viewを実装します。
Laravelで実装
Route実装
まずはControllerにアクセスできるよう、Routeを設定しましょう。
<?php // ログイン前アクセス可能(Google OAuth認証) Route::group(['prefix' => '/login/google', 'namespace' => 'Auth'], function ($router) { $router->get('/', 'LoginController@index')->name('login'); $router->get('/redirect', 'LoginController@getRedirect'); $router->get('/callback', 'LoginController@getCallback'); });
Controller実装
AuthでLoginコントローラがあるはずなので、
Loginコントローラを編集します。
app/Http/Controller/Auth/LoginController.php
<?php use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Support\Facades\Auth; use App\Models\User as UserModel; // 私はModelディレクトリ配下にUserModelを置いてるので use Socialite; // Socialite使用可能にする class LoginController extends BaseController { use AuthenticatesUsers; private $user_model; public function __construct(UserModel $user_model) { $this->middleware('guest:admin')->except('logout'); $this->user_model = $user_model; //Usermodelをインスタンス化 } /** * エラーの有無を確認して、ログインページにリダイレクト * * @return response * @access public */ public function index() { Auth::logout(); return $this->render(); } /** * Google認証ページヘユーザーをリダイレクト * * @return \Illuminate\Http\Response * @access public */ public function getRedirect() { return Socialite::driver('google')->redirect(); } /** * Googleからユーザー情報を取得、ログイン権限があればログイン * * @return \Illuminate\Http\Response * @access public */ public function getCallback() { $email = Socialite::driver('google')->stateless()->user()->email; $user = $this->user_model->getAdminUserFromEmail($email); // すでに登録しているユーザとemailが一致するか確認 if ($user === null) { return redirect() ->route('login') ->with('message', 'ログイン権限がありません。'); } Auth::login($user, true); //弾かれなければ$userオブジェクトを用いてログイン return redirect($this->redirectTo); //ログイン後リダイレクト } }
Model実装
そしてこのUserModelでemailからユーザの有無判定。
(パスワードは使用しないので、消してしまって大丈夫です。)
<?php /** * 特定のEmailから管理ユーザを取得 * * @param str $email * @return object * @access public */ public function getAdminUserFromEmail(string $email) { return $this->where('email', $email) ->first(); }
Viewの実装
最後に、Viewを設定して、、、
<a href="/login/google/redirect" class="btn btn-google">Sign in using Google+</a>
ログインできれば、完了です!
な、なんて便利なんでしょう・・・!!!!涙