【Laravel6】SocialiteでGitHubアカウントを使用した認証システムの実装方法

##Socialiteとは
[Socialite](https://github.com/laravel/socialite)は複雑なSNS認証を高機能で使いやすいインターフェイスとして手軽に組み込めるパッケージです。
今回はSocialiteを使用してGitHubのOAuth認証を実装しますが、GitHub以外にもFacebook、Twitter、Google、LinkedIn、GitLab、 Bitbucket等に対応しています。

##実装する上での流れ
1. GitHub上でOAuth認証の準備
2. Webアプリ側でOAuth認証の準備
3. OAuth認証の実装

##1.GitHub上でOAuth認証の準備
はじめにGitHub上でOAuthアプリケーションの作成を行います。
GitHubにログインして、
[Settings]→[Developer Settings]→[OAuth Apps]→[New OAuth App]と画面遷移します。

以下三つの項目を入力します。
・Application Name（Webアプリケーションの名前）
・Homepage URL（ホームページのURL）
・Authorization callback URL（GitHubで認証が完了した後の戻り先のURL）
<img width="562" alt="スクリーンショット 2020-03-17 1.26.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283595/087b3754-8461-9749-337b-9e6557e0193b.png">

入力後に[Register application]を押下すると、以下の値が発行されます。

```
・Client ID
・Client Secret
```

##2.Webアプリ側でOAuth認証の準備

#####2-1 LaravelのAuth認証を導入する。

```
$ php artisan make:auth 
```
もしコマンド実行後にエラーが出る場合は[こちらの記事](https://qiita.com/hetare_phper/items/8e37c53ced7b419519b4)を参考にしてみてください。

#####2-2 Laravel Socialiteを導入する。

```
$ composer require laravel/socialite
```

#####2-3 `config/app.php` にサービスプロバイダを追加する。
socialiteをサービスプロバイダーに追加することにより、Laravel起動時にsocialiteも同時に初期処理として起動します。

```app.php
'providers' => [
  ...
  'Socialite' => Laravel\Socialite\Facades\Socialite::class,
],
```

#####2-3 `config/app.php` にエイリアスを追加する。

```app.php
'aliases' => [
  ...
  'Socialite' => Laravel\Socialite\Facades\Socialite::class,
],
```

#####2-4 `.env` に認証情報等を追記する。
WebアプリケーションとGitHub間での連携を行うために、以下を追記します。

```.env
GITHUB_CLIENT_ID=(1.GitHub上でOAuth認証の準備で生成された値)
GITHUB_CLIENT_SECRET=(1.GitHub上でOAuth認証の準備で生成された値)
GITHUB_URL=(1.GitHub上でOAuth認証の準備で指定した戻り先のURL)
```

##3.OAuth認証の実装
ここまででGitHubのOAuth認証を導入するための準備は完了しましたので、実態にOAuth認証の実装を行って行きます。

#####3-1 `ルーティング` を定義する。
まずはGitHub認証経由でログインする際のルーティングを `web.php` ファイルに定義します。

```web.php
// GitHubの認証ページに遷移するためのルーティング
Route::get('login/github', 'Auth\LoginController@redirectToProvider');

// GitHubの認証後に戻るためのルーティング
Route::get('/login/callback/github', 'Auth\LoginController@handleProviderCallback');
```
#####3-2 `コントローラー` 内に処理を実装する。
次に、3-1で定義したコントローラー内に認証に必要な処理を実装しましょう。

```Auth\LoginController.php
/**
 * GitHubの認証ページヘユーザーを転送するためのルート
 *
 * @return \Symfony\Component\HttpFoundation\RedirectResponse
 */
 public function redirectToProvider() {
   return Socialite::driver("github")->redirect();
 }

/**
 * GitHubの認証後に戻るルート
 *
 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
 */
 public function handleProviderCallback() {
   try {
     $user = Socialite::with("github")->user();
   } catch (Exception $e) {
     return redirect('/welcome'); // エラーならウェルカムページに転送
   }

   // nameかnickNameをuserNameにする
   if ($user->getName()) {
     $userName = $user->getName();
   } else {
     $userName = $user->getNickName();
   }

   // mailアドレスおよび名前を保存
   $authUser = User::firstOrCreate([
     'email' => $user->getEmail(),
     'name' => $userName
   ]);
   auth()->login($authUser); // ログイン
   return redirect()->to('/home'); // homeページに転送
 }
```

#####3-3 `usersテーブル` を修正する。
GitHub認証経由でアカウントを登録した場合には、usersテーブルのpasswordカラムはnullになるので、デフォルトのままではエラーになってしまいます。そのためnullを許容するように修正します。

```create_users_table.php
public function up()
  {
    Schema::create('users', function (Blueprint $table) {
      ...
      $table->string('password')->nullable(); // nullable()を追加
      ...
    });
  }
```

#####3-4 Viewに `リンク` を追加する。
最後に、GitHub認証に遷移するための、リンクを任意のViewに付けます。
今回はwelcomeページにリンクを追加しました。

```welcome.blade.php
<div class="links">
  <a href="<?php echo url("/login/github"); ?>" >Github</a>
</div>
```

##最後に
以上で、GitHub経由の認証機能を実装することができました。
思っていた以上に簡単に実装できたと思ったけど、Socialiteのお陰ですね。感謝です。