はじめに
今回はプロダクト作成の際に使用したLaravel SocialiteによるOAuth認証と、Laravel Passportによるユーザー認証の組み合わせについてお話しようと思います。
まずOAuth認証については@TakahikoKawasaki様作成の以下の記事がとてもわかりやすかく参考になりましたのでご参照ください。
Laravel Socialiteとは?
Laravel Socialiteは、LaravelによるWebアプリケーションでのソーシャル認証をサポートするライブラリです。
Laravel上で、OAuth2.0によるWeb APIの認証、OAuth認証が実装できるようになります。
Laravel SocialiteでOAuth認証を実装することには、いくつかの利点があります。
セキュリティ
Socialiteは、OAuth 1.0やOAuth 2.0のセキュリティベストプラクティスに従っており、安全な認証フローを提供します。
また、ステートレスモードを利用することで、APIベースのアプリケーションでも安全に認証を行うことができます。
簡単な設定と使いやすさ
Laravel Socialiteは、Laravelの公式パッケージであり、Laravelフレームワークと深く統合されており、設定や使用が非常に簡単です。
OAuth認証の実装
今回はLaravel SocialiteでSpotifyアカウントのOAuth認証を実装する。といった前提でやっていきます。
前提条件
- Laravelアプリケーションが設定済み
- Spotify Developerアカウントを登録し、クライアントIDとクライアントシークレットを取得済み、リダイレクトURIを設定済み
Laravel Socialite、Passportの設定
今回Laravel Passportはユーザー認証に使用します。
Laravel Socialiteはソーシャル認証を簡単に実装するためのライブラリであり、APIトークンの生成は行いません。
APIトークンの生成は、Laravel Passportなどの別のパッケージを使用して行います。
SocialiteとPassportを組み合わせることで、ソーシャルメディア認証とAPIトークン認証をスムーズに実装することができます。
ターミナルで以下のコマンドを実行して、Laravel SocialiteとLaravel Passportをインストールします。
composer require laravel/socialite laravel/passport
config/app.phpで、サービスプロバイダーに下記を追加します。
'providers' => [
Laravel\Passport\PassportServiceProvider::class,
Laravel\Socialite\SocialiteServiceProvider::class,
SocialiteProviders\Manager\ServiceProvider::class,
],
'aliases' => [
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
],
次にマイグレーションを実行して必要なテーブルを作成します。
必要なマイグレーションファイルはLaravel Passportをインストールした時点で作成されます。
php artisan migrate
更にサーバーとのやり取りに必要な暗号鍵を生成するために以下のコマンドを実行します。
php artisan passport:install
ユーザーモデル (Models/User.php) にHasApiTokensトレイトを追加します。
HasApiTokensトレイトを追加することによって、そのモデルがAPIトークンを生成、管理、検証するための機能を利用できるようになります。
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
Spotifyアカウントの設定
Spotify Developer Dashboardにアクセスし、設定したリダイレクトURI、取得したクライアントID、クライアントシークレットをコピーして、それぞれ.envファイルに環境変数として設定します。
SPOTIFY_CLIENT_ID=your_spotify_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
SPOTIFY_REDIRECT_URI=https://yourapp.com/callback
OAuth認証におけるリダイレクトURIとは、ユーザーが認証後にリダイレクトされるアドレスです。
リダイレクトURIを受け取り、ルートでコントローラにデータを渡す。といった流れになります。
Spotifyアカウント側と環境変数側で設定を一致させます。
コントローラーの作成
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Http;
class AuthController extends Controller
{
public function redirectToSpotify()
{
/** @var SocialiteProviders\Spotify\Provider $driver */
$driver = Socialite::driver('spotify');
return $driver->stateless()->redirect();
}
public function handleSpotifyCallback()
{
try {
/** @var SocialiteProviders\Spotify\Provider $driver */
$driver = Socialite::driver('spotify');
$spotifyUser = $driver ->stateless()->user();
$user = User::updateOrCreate(
['spotify_id' => $spotifyUser->getId()],
[
'name' => $spotifyUser->getName(),
'email' => $spotifyUser->getEmail(),
'avatar' => $spotifyUser->getAvatar(),
'spotify_access_token' => $spotifyUser->token,
'spotify_refresh_token' => $spotifyUser->refreshToken,
'spotify_token_expires_at' => now()->addSeconds($spotifyUser->expiresIn),
]
);
Auth::login($user, true);
$userId = $user->id;
$tokenResult = $user->createToken('Laravel Token');
$token = $tokenResult->accessToken;
session(['spotify_access_token' => $spotifyUser->token,
'token' => $tokenResult->accessToken,
'user_id' => $user->id]);
$token = $tokenResult->accessToken;
return redirect('/Top')
} catch (\Exception $e) {
Log::error('Spotify認証エラー: ' . $e->getMessage());
Log::error('例外の詳細: ' . $e);
}
}
}
上記のコード、redirectToSpotify()では、
Socialiteが対応している複数のソーシャルメディアプロバイダー(Google、Facebook、Twitterなど)の中から、Spotifyを選択し、OAuthプロバイダー(ユーザーの認証と認可を管理し、サービスを提供する組織やプラットフォーム)を取得後、Spotifyの認証ページにリダイレクトしています。
次にhandleSpotifyCallback()
このコードは、SpotifyからのOAuth認証コールバックを処理するメソッドです。
SocialiteでSpotifyからのユーザー情報を取得し、その情報を基にアプリケーション内のユーザーを作成または更新し、ユーザーをログインさせます。
SpotifyでのユーザーIDがこのプロダクト内でのユーザーアカウントと紐づけられます。
その後でLaravel Passportを使用し、APIトークンを生成、セッションにSpotifyから発行されたアクセストークンと、Laravel Passportで生成されたAPIトークン、そしてログインしたユーザーIDを保存し、Topページにリダイレクトします。
上記のコードに適切なルートやフロントエンドを作成することでOAuth認証が行えるはずです。
まとめ
Laravel SocialiteによるOAuth認証と、Laravel Passportによるユーザー認証についてお話させていただきました。
今回プロダクト作成のためにOAuth認証を行っているときは、とにかく実装をするために、エラーを解消するためにと目の前のことで一杯になっていましたが、こうして流れとしてまとめてみると設定が一つでもないと成り立たないほどにかみ合っているように思いました。
自分も含めて大抵の人は、実装したことがない技術、もしくは構築環境が違う記事などは見ていても難しそうといった苦手意識が浮かぶと思いますが、こういった流れをなんとなくでも理解しておくと苦手意識が薄まり、実装する時の助けになると、実感しています。
長い文章を読んでくださり、ありがとうございました!