【Laravel】Socialite・Microsoft Graphを使用しOAuth認証

## 目的
本記事の目的は、Laravelの[Socialite](https://readouble.com/laravel/5.8/ja/socialite.html)・[Microsoft Graph](https://docs.microsoft.com/ja-jp/graph/overview)を使用し、[OAuth認証](https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be)で[Microsoftアカウント](https://support.microsoft.com/ja-jp/windows/microsoft-%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%A8%E3%81%AF-4a7c48e9-ff5a-e9c6-5a5c-1a57d66c3bfa)のユーザー情報を取得することです。

## 前提

|  フレームワーク・ライブラリ  |  バージョン  |
| ---- | ---- |
|  PHP  |   7.3  |
|  Laravel  |  5.8.36  |
|  socialiteproviders/microsoft-graph  |  3.*  |

適宜、各自の環境に合わせたバージョンを使用してください。

## 手順

|  手順  |  概要  |
| ---- | ---- |
|  [手順1](#手順1-microsoft-azure-directory-admin-centerで各種設定)  |   Microsoft Azure Directory admin centerで各種設定  |
|  [手順2](#手順2-socialiteprovidersmicrosoft-graphをインストール)  |  socialiteproviders/microsoft-graphをインストール  |
|  [手順3](#手順3-設定) |  設定  |
|  [手順4](#手順4-ルート)  |  ルート  |
|  [番外編](#番外編)  |  Socialiteの便利なメソッド  |

- ComposerやLaravelのインストール等の環境構築は各自で行ってください。
- [Microsoftアカウント](https://support.microsoft.com/ja-jp/windows/microsoft-%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%A8%E3%81%AF-4a7c48e9-ff5a-e9c6-5a5c-1a57d66c3bfa)は各自で用意してください。

### 手順1 Microsoft Azure Directory admin centerで各種設定

[こちら](https://blog.hrendoh.com/oauth-to-microsoft-graph-with-laravel-5-8/#Azure_Active_Directory-2)の記事がわかりやすいので参考にしてください。

### 手順2 socialiteproviders/microsoft-graphをインストール

```
composer require socialiteproviders/microsoft-graph
```

バージョンを指定する場合は`composer require socialiteproviders/microsoft-graph 3.*`

### 手順3 設定

```config/app.php
'providers' => [
    // ...
    \SocialiteProviders\Manager\ServiceProvider::class, 
],
```

```app/Providers/EventServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        // 下記を追加
        \SocialiteProviders\Manager\SocialiteWasCalled::class => [
            'SocialiteProviders\\Graph\\GraphExtendSocialite@handle',
        ],
        // ここまで
    ];

    /**
     * Register any events for your application.
     */
    public function boot(): void
    {
        parent::boot();
    }
}
```

```config/services.php
return [
    'graph' => [
        'client_id' => env('GRAPH_CLIENT_ID'),
        'client_secret' => env('GRAPH_CLIENT_SECRET'),
        'redirect' => env('GRAPH_REDIRECT_URI')
    ],
];
```

[こちら](https://blog.hrendoh.com/oauth-to-microsoft-graph-with-laravel-5-8/#Azure_Active_Directory-2)の記事を参考にして設定した値を入力してください。

```env
GRAPH_CLIENT_ID=client_id
GRAPH_CLIENT_SECRET=secret_key
GRAPH_REDIRECT_URI=設定したリダイレクトURL
```

### 手順4 ルート

```routes/web.php
Route::get('login/graph', 'Auth\LoginController@redirectToProvider');
Route::get('login/graph/callback', 'Auth\LoginController@handleProviderCallback');
```

```app/Http/Controllers/Auth/LoginController.php

namespace App\Http\Controllers\Auth;

use Socialite;

class LoginController extends Controller
{
    /**
     * Microsoftの認証ページヘユーザーをリダイレクト
     *
     * @return \Illuminate\Http\Response
     */
    public function redirectToProvider()
    {
        return Socialite::driver('graph')->redirect();
    }

    /**
     * Microsoftからユーザー情報を取得
     *
     * @return \Illuminate\Http\Response
     */
    public function handleProviderCallback()
    {
        $user = Socialite::driver('graph')->user();
        dd($user); // 出力
    }
}
```

ddでユーザー情報が取得できているはずです。
公式の[GitHub](https://github.com/microsoftgraph/msgraph-training-phpapp/tree/main/demo/graph-tutorial)で参考コードが多く載せられています。

### 番外編

[Socialit](https://readouble.com/laravel/5.8/ja/socialite.html)の便利なメソッドの紹介です。

API開発の場合はstatelessメソッドが便利です。

```php
return Socialite::driver('graph')->stateless()->user();
```

オプションのパラメータはwithメソッドが便利です。オプションのパラメータの詳細は、[公式サイト](https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code)でご確認ください。例えば、redirectToProviderアクションからhandleProviderCallbackアクションまで状態を保持したい場合は、stateオプションを使用することができます。

```php

    public function redirectToProvider()
    {
        return Socialite::driver('graph')->with(['state' => 'hoge'])->redirect();
    }

    public function handleProviderCallback(Request $request)
    {
        dd($request['state']); // hogeが出力される
        $user = Socialite::driver('graph')->user();
    }
```


## 参考

- [https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code](https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code)
- [https://github.com/microsoftgraph/msgraph-training-phpapp/tree/main/demo/graph-tutorial](https://github.com/microsoftgraph/msgraph-training-phpapp/tree/main/demo/graph-tutorial)
- [https://readouble.com/laravel/5.8/ja/socialite.html](https://readouble.com/laravel/5.8/ja/socialite.html)
- [https://blog.hrendoh.com/oauth-to-microsoft-graph-with-laravel-socialite/#socialiteprovidersmicrosoft-graph](https://blog.hrendoh.com/oauth-to-microsoft-graph-with-laravel-socialite/#socialiteprovidersmicrosoft-graph)
- [https://qiita.com/chtzmrtshgh/items/802fd447804eef78bdce](https://qiita.com/chtzmrtshgh/items/802fd447804eef78bdce)