【Laravel × React】SPA認証を用いた簡単なアプリ作った時に躓いたアレコレ

前の記事から長らく経ってしまいました、、、
職場の引継ぎであったり、家庭の事情でなかなか個人開発の方が進められなかったと言い訳しておきます。(Recpoolに関しては、現段階では通知機能の実装をかなり細々とやっております。。)

さて、今回は laravel × React でSPA認証(Twitter認証)を使った簡単なアプリを作った際に、詰まった点をメモとして残しておきます。

https://shikuziri-todo-app.herokuapp.com/

>「しくじりTODO」は、**作成したTODOリストからその日に達成できなかったTODOを皆でシェアしよう！というアプリ**です。製作期間としては約10日ほどです。


Twitterは意識が高い方が多いので、なかなか自分のやるべき事が進まなかった時にTwitter開くと、「なんで俺はこんなにできないんだ、、」という自己嫌悪に陥った経験から、「明日やろうは馬鹿野郎でもええやないか」精神で思い付きで制作しました。

TODOをシェアという部分でTwitterでのSNSシェアは必須なのですが、OGP設定や動的OGP画像生成の問題が現段階ではなかなかクリアできずTwitterでシェアが出来ない感じになってます。
最大の問題点なので早急に解決策を考えてます。

**SPA認証にかなーり詰まってしまったのと、Laravelを理解するのに90%ぐらい時間が掛かりました、、、(同じような初学者の境遇の方で何らかの形で助けになれればと思います、、、)**


##前提

今回使用した各種バージョンは以下の通り。

|  Package  |  version  |
| ---- | ---- |
|  React  |  v17.0.2  |
|  TypeScript  |  v4.5.5  |
|  php  |  v7.3  |
|  laravel/framework  |  v8.75  |
| laravel/socialite | v5.5 |
| laravel/sanctum | v2.11 |

##環境構築
ここに関しては特に問題ないかと思います。
偉大なる先人の方々が分かりやすく記事をまとめておられます。感謝、、、圧倒的感謝、、、！


https://qiita.com/morry_48/items/abd620f051fb4f36dcc2

https://www.alt-plus.jp/archives/2625

##Laravel Socialiteを用いてSNS連携(Twitterアカウント)

Twitter Developersからアプリの作成、およびSocialiteのインストールと設定等は
偉大なる先人の知見およびGoogle先生よりお願いします。

###ハマりポイント①　SocialiteのドライバーからTwitterの認証ページにリダイレクトする処理のルート設定

React × Laravel を用いて SPA化する際には、/api/*以外のURLに対してアクセスが来た時に応答するルートとしてapi以外にアクセスが来たときは XXXXX.blade.phpが応答するように設定していると思います。

```wep.php
Route::get('{any}',function (){
    return view('XXXXX');
}) ->where('any', '.+');
```

正規表現を使って、Twitterの認証ページヘユーザーをリダイレクトする処理とTwitterからユーザー情報を取得する処理のルートのアクセスだけ避ける事も考えたのですが、ごちゃごちゃするからapi.phpの方でルート設定しちゃえ！と思い設定してしまいました。。。(今思うとアホですが。ここで大きく詰まってしまいました。)

それもそのはずです。

``Socialite::driver('XXXX')のredirectメソッドには通常はセッションを使うようになっているため、ステートレスであるroutes/api.phpのルートは使用できません。``
また、statelessメソッドを使用して、セッション状態の検証を無効にする事は可能ですが
**ステートレス認証は、認証にOAuth1.0を使用するTwitterドライバでは使用できません。**

結局、web.phpにルート設定しました。
twitterを含むアクセスが来たときは XXXXX.blade.phpの応答を弾く感じです。

```wep.php
Route::get('/{any?}',function (){
    return view('welcome');
}) ->where('any', '(?!.+twitter).+');

Route::get('/login/twitter', [App\Http\Controllers\Auth\LoginController::class, 'getProviderOAuthURL']);
Route::get('/login/twitter/callback', [App\Http\Controllers\Auth\LoginController::class, 'handleCallBack']);
```


**LaravelのルーティングおよびSocialiteの理解度の低さが招いた躓きでした。**


以下参考。

>すべてのLaravelルートは、routesディレクトリにあるルートファイルで定義します。これらのファイルは、
アプリケーションのApp\Providers\RouteServiceProviderにより、自動的に読み込まれます。
routes/web.phpファイルは、Webインターフェイス用のルートを定義します。これらのルートには、セッション状態やCSRF保護などの機能を提供するwebミドルウェアグループが割り当てられます。routes/api.phpのルートはステートレスであり、apiミドルウェアグループが割り当てられています。
[Laravel 8.X ルーティング](https://readouble.com/laravel/8.x/ja/routing.html)より参照

https://qiita.com/near108/items/820058f690b4f0f4192a#socialitedrivergoogle-redirect

https://readouble.com/laravel/8.x/ja/socialite.html

###ハマりポイント② API(/login/twitter)を叩いたら、SNS認証用のリダイレクトURLが返ってくると思いきやInternal Server Errorが返ってきた。


####エラー内容
![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1913276/2164f78a-262e-b1f7-f494-d48342765f5c.png)

```
cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
```
####原因
localhostからcurlでhttps通信を行う際にCA証明書がphp.iniで正しく設定されていない
####解決方法
1.クライアント証明書をphp.initで指定する
2.Guzzle側のオプションで「証明書の検証無し」を指定する

今回は1の方法で解決しました。

以下参考です。

https://github.com/yabacon/paystack-php/wiki/cURL-error-60:-SSL-certificate-problem:-unable-to-get-local-issuer-certificate-(see-http:--curl.haxx.se-libcurl-c-libcurl-errors.html)

##Laravel SanctumでSPA認証


以下参考

https://qiita.com/ucan-lab/items/3e7045e49658763a9566

https://www.aska-ltd.jp/jp/blog/215

https://readouble.com/laravel/8.x/ja/sanctum.html