Webアプリ習作#12

ツイート一覧画面からのログイン

index.blade.phpTwitterログインへのリンク(twitter.login)を追加する

ルーティング

routes/web.phpを修正

Route::prefix('auth')->group(function () {
    Route::get('twitter', 'TwitterAuthController@login')->name('twitter.login'); // ここを修正.
    Route::get('twitter/callback', 'TwitterAuthController@callback');
});
ルーティング確認
php artisan route:list
+--------+----------+-----------------------+---------------+-----------------------------------------------------+--------------+
| Domain | Method   | URI                   | Name          | Action                                              | Middleware   |
+--------+----------+-----------------------+---------------+-----------------------------------------------------+--------------+
|        | GET|HEAD | /                     |               | App\Http\Controllers\TweetController@index          | web          |
|        | GET|HEAD | api/user              |               | Closure                                             | api,auth:api |
|        | GET|HEAD | auth/twitter          | twitter.login | App\Http\Controllers\TwitterAuthController@login    | web          |
|        | GET|HEAD | auth/twitter/callback |               | App\Http\Controllers\TwitterAuthController@callback | web          |
+--------+----------+-----------------------+---------------+-----------------------------------------------------+--------------+
ログインへのリンクを追加

resources/views/tweets/index.blade.phpを修正

<body>

// ここからを追加.
  <a href="{{ route('twitter.login') }}">Twitterでログイン</a>
// ここまでを追加.

  @foreach($tweets as $tweet) 
    <div>
      <img src="{{ $tweet->user->avatar }}" width="48" height="48">
      {{ $tweet->user->name }}
      {{ $tweet->created_at->format('Y/m/d H:i') }}
    </div>
    <div>
      {!! nl2br(e( $tweet->body )) !!}
    </div>
  @endforeach

</body>
確認

http://localhost:8000/にアクセス
一番上に"Twitterでログイン"のリンクが表示されるのでクリックしてログインができるかを確認
(確認前に一旦Twitterからログアウトしておく)

ツイート一覧画面からのテストツイート

resources/views/tweets/index.blade.phpにテストツイートボタンを作る

ルーティング

routes/web.phpを修正

Route::get('/', 'TweetController@index');
Route::post('tweets', 'TweetController@store')->name('tweets.store'); // ここを追加.

Route::prefix('auth')->group(function () {
    Route::get('twitter', 'TwitterAuthController@login')->name('twitter.login');
    Route::get('twitter/callback', 'TwitterAuthController@callback');
});
ルーティング確認
php artisan route:list
+--------+----------+-----------------------+---------------+-----------------------------------------------------+--------------+
| Domain | Method   | URI                   | Name          | Action                                              | Middleware   |
+--------+----------+-----------------------+---------------+-----------------------------------------------------+--------------+
|        | GET|HEAD | /                     |               | App\Http\Controllers\TweetController@index          | web          |
|        | GET|HEAD | api/user              |               | Closure                                             | api,auth:api |
|        | GET|HEAD | auth/twitter          | twitter.login | App\Http\Controllers\TwitterAuthController@login    | web          |
|        | GET|HEAD | auth/twitter/callback |               | App\Http\Controllers\TwitterAuthController@callback | web          |
|        | POST     | tweets                | tweets.store  | App\Http\Controllers\TweetController@store          | web          |
+--------+----------+-----------------------+---------------+-----------------------------------------------------+--------------+
テストツイートボタンの追加

resources/views/tweets/index.blade.phpを修正

<body>

  <a href="{{ route('twitter.login') }}">Twitterでログイン</a>

// ここからを追加.
  <form method="POST" action="{{ route('tweets.store') }}">
    @csrf
    <button type="submit">テストツイート</button>
  </form>
// ここまでを追加.

  @foreach($tweets as $tweet) 
    <div>
      <img src="{{ $tweet->user->avatar }}" width="48" height="48">
      {{ $tweet->user->name }}
      {{ $tweet->created_at->format('Y/m/d H:i') }}
    </div>
    <div>
      {!! nl2br(e( $tweet->body )) !!}
    </div>
  @endforeach

</body>
ツイートをDBに保存する処理の作成

TweetControllerにstoreメソッドを作成しそこでツイートすると同時にDBに保存する
app/Http/Controllers/TweetController.phpを修正

use App\Models\Tweet;
use Illuminate\Http\Request;
// ここからを追加.
use Auth;
use Socialite;
use Abraham\TwitterOAuth\TwitterOAuth;
// ここまでを追加.

class TweetController extends Controller
{
    public function index()
    {
        $tweets= Tweet::all()->sortByDesc('created_at');
        return view('tweets.index', ['tweets' => $tweets]);
    }

// ここからを追加.
    public function store()
    {
        $user = Socialite::driver('Twitter')->user();
        $twitter = new TwitterOAuth( env('TWITTER_CLIENT_ID'),
            env('TWITTER_CLIENT_SECRET'),
            $user->token,
            $user->tokenSecret );

        $body = 'テストツイートです';
    
        $twitter->post("statuses/update", [
           "status" =>
                $body
            ]);
    
        $tweet = new Tweet();
        $tweet->body = $body;
        $tweet->user_id = Auth::user()->id;
        $tweet->save();
    }
// ここまでを追加.
}

※エラー発生

$user = Socialite::driver('Twitter')->user();

上記実行時に下記エラーが発生する

Invalid request. Missing OAuth verifier.

Twitterのログインが成功した後ならSocialite::driver('Twitter')->user()を呼ぶたびにユーザー情報を取得できると思い込んでいたがどうやらそうではない模様
ログイン直後に得たユーザー情報をDBに格納するかセッションに覚えさせる必要があるとのこと
参考:https://stackoverflow.com/questions/42193340/laravel-socialite-invalid-request-missing-oauth-verifier-twitter