
前提・実現したいこと
EC2にデプロイしたLaravelアプリケーションに、Twitterアカウントを使ったログイン認証機能の実装に挑戦しています。
dockerを活用した開発環境(LEMP環境)では正常にTwitter認証が機能していますが、 EC2にデプロイしてTwitter認証の動作確認をすると、コールバック時に開発環境では出ない【404 Not Found】が返ります。
発生している問題・エラーメッセージ
404 Not Found
該当のソースコード
.env(実際には入力されています)
TWITTER_CLIENT_ID="<ID>" TWITTER_CLIENT_SECRET="<SECRET>" TWITTER_CLIENT_ACCESS_TOKEN="<ACCESS_TOKEN>" TWITTER_CLIENT_ACCESS_TOKEN_SECRET="<ACCESS_TOKEN_SECRET>"
app/Http/Controllers/Auth/LoginController.php
PHP
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\User; use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; use Laravel\Socialite\Facades\Socialite; class LoginController extends Controller { public function __construct() { $this->middleware('guest')->except('logout'); } public function redirectToProvider(string $provider) { return Socialite::driver($provider)->redirect(); } public function handleProviderCallback(Request $request, string $provider) { $providerUser = Socialite::driver($provider)->user(); if($provider === 'google') { $user = User::where('email', $providerUser->getEmail())->first(); } elseif($provider === 'twitter') { $user = User::where('twitter_id', $providerUser->getId())->first(); } if ($user) { $this->guard()->login($user, true); return $this->sendLoginResponse($request); } if($provider === 'google') { return redirect()->route('register.{provider}', [ 'provider' => $provider, 'email' => $providerUser->getEmail(), 'token' => $providerUser->token, ]); } elseif($provider === 'twitter') { return redirect()->route('register.{provider}', [ 'provider' => $provider, 'twitter_id' => $providerUser->getId(), 'token' => $providerUser->token, 'tokenSecret' => $providerUser->tokenSecret, ]); } } }
app/Http/Controllers/Auth/RegisterController.php
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use App\User; use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Laravel\Socialite\Facades\Socialite; class RegisterController extends Controller { use RegistersUsers; protected $redirectTo = RouteServiceProvider::HOME; public function __construct() { $this->middleware('guest'); } protected function validator(array $data) { return Validator::make($data, [ 'name' => ['required', 'string', 'alpha_num', 'min:3', 'max:16', 'unique:users'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'string', 'min:8', 'confirmed'], ]); } protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), ]); } public function showProviderUserRegistrationForm(Request $request, string $provider) { $token = $request->token; $providerUser = Socialite::driver($provider); //google if ($provider === 'google') { $providerUser = $providerUser->userFromToken($token); return view('auth.social_register', [ 'provider' => $provider, 'email' => $providerUser->getEmail(), 'token' => $providerUser->token, ]); //twitter } elseif ($provider === 'twitter') { $tokenSecret = $request->tokenSecret; $providerUser = $providerUser->userFromTokenAndSecret($token, $tokenSecret); return view('auth.social_register', [ 'provider' => $provider, 'twitter_id' => $providerUser->getId(), 'token' => $providerUser->token, 'tokenSecret' => $providerUser->tokenSecret, ]); } } public function registerProviderUser(Request $request, string $provider) { //google if($provider === 'google') { $request->validate([ 'name' => ['required', 'string', 'min:3', 'max:15', 'unique:users'], 'age' => ['numeric', 'min:1', 'max:100', 'nullable'], 'token' => ['required', 'string'], ]); //twitter } elseif($provider === 'twitter') { $request->validate([ 'name' => ['required', 'string', 'min:3', 'max:15', 'unique:users'], 'age' => ['numeric', 'min:1', 'max:100', 'nullable'], 'token' => ['required', 'string'], 'tokenSecret' => ['required', 'string'], ]); } $token = $request->token; $providerUser = Socialite::driver($provider); //google if ($provider === 'google') { $providerUser = $providerUser->userFromToken($token); //twitter } elseif ($provider === 'twitter') { $tokenSecret = $request->tokenSecret; $providerUser = $providerUser->userFromTokenAndSecret($token, $tokenSecret); } //google if ($provider === 'google') { $user = User::create([ 'name' => $request->name, 'email' => $providerUser->getEmail(), 'password' => null, ]); //twitter } elseif ($provider === 'twitter') { $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'twitter_id' => $providerUser->getId(), 'password' => null, ]); } $this->guard()->login($user, true); return $this->registered($request, $user) ?: redirect($this->redirectPath()); } }
config/services.php
PHP
<?php return [ /* |-------------------------------------------------------------------------- | Third Party Services |-------------------------------------------------------------------------- | | This file is for storing the credentials for third party services such | as Mailgun, Postmark, AWS and more. This file provides the de facto | location for this type of information, allowing packages to have | a conventional file to locate the various service credentials. | */ 'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), ], 'postmark' => [ 'token' => env('POSTMARK_TOKEN'), ], 'ses' => [ 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ], 'google' => [ 'client_id' => env('GOOGLE_CLIENT_ID'), 'client_secret' => env('GOOGLE_CLIENT_SECRET'), 'redirect' => env('APP_URL') . '/login/google/callback', ], 'twitter' => [ 'client_id' => env('TWITTER_CLIENT_ID'), 'client_secret' => env('TWITTER_CLIENT_SECRET'), 'redirect' => env('APP_URL') . '/login/twitter/callback', ], ];
routes/web.php
<?php Auth::routes(); Route::prefix('login')->name('login.')->group(function () { Route::get('/{provider}', 'Auth\LoginController@redirectToProvider')->name('{provider}'); Route::get('/{provider}/callback', 'Auth\LoginController@handleProviderCallback')->name('{provider}.callback'); }); Route::prefix('register')->name('register.')->group(function () { Route::get('/{provider}', 'Auth\RegisterController@showProviderUserRegistrationForm')->name('{provider}'); Route::post('/{provider}', 'Auth\RegisterController@registerProviderUser')->name('{provider}'); }); if (app()->environment('production')) { URL::forceScheme('https'); }
試したこと
Callback URL/Redirect URLの整合性チェック
補足情報(FW/ツールのバージョンなど)
OAuth 2.0
まだ回答がついていません
会員登録して回答してみよう