質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

コールバック

コールバックは他のコードに引数として渡されるコードのことを指します。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。

解決済

【EC2】LaravelでTwitter認証をするとコールバックで『404 Not Found』が返される(開発環境ではエラーが出ない)

NULL_000000
NULL_000000

総合スコア3

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

コールバック

コールバックは他のコードに引数として渡されるコードのことを指します。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。

1回答

0評価

0クリップ

547閲覧

投稿2021/12/17 21:23

前提・実現したいこと

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

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

退会済みユーザー

退会済みユーザー

2021/12/18 03:01

.envのAPP_URLはhttpsで指定していますか?
NULL_000000

2021/12/18 04:37

はい。httpsで指定しております。 Google認証を既に実装していまして、こちらは開発環境、本番環境ともに正常に動作しています。 開発環境でTwitter認証を実装、正常に動作することを確認した後にデプロイしました。 ソースの変更は本番環境に反映されておりTwitterアカウントの認証画面までは遷移できますが、現状ではコールバックがうまく動作していない状態です。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

コールバック

コールバックは他のコードに引数として渡されるコードのことを指します。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。