skip to Main Content

I’m working on integrating Twitter OAuth using Laravel Socialite in a stateless API for a Single Page Application (SPA). I’m encountering an error when trying to generate the authorization URL.

Problem:
When calling the redirect() method on the Twitter Socialite driver, I’m getting the following error:

Session store not set on request.

Here’s the relevant part of my controller:

public function getSocialRedirect(Request $request, string $provider)
{
    try {
        $url = Socialite::driver('twitter')
            ->stateless()
            ->scopes($scopes)
            ->with(['state' => $state])
            ->redirect()
            ->getTargetUrl();

        return response()->json([
            'url' => $url,
        ]);
    } catch (Exception $e) {
        throw $e;
    }
}

I also added this in my config, for use oauth2

'twitter' => [
        'enabled'       => env('TWITTER_ENABLED', false),
        'client_id'     => env('TWITTER_CLIENT_ID'),
        'client_secret' => env('TWITTER_CLIENT_SECRET'),
        'redirect'      => env('TWITTER_REDIRECT_URI'),
        'oauth'         => 2
    ]

I’ve used the stateless() method as suggested in the Socialite documentation for API usage.
The route is in routes/api.php

How can I generate a Twitter OAuth authorization URL using Laravel Socialite in a completely stateless manner, suitable for use in a SPA? Is there a way to bypass the session requirement altogether?
Any insights or alternative approaches would be greatly appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    The Socialite package's Twitter provider has a design assumption that doesn't work well in an API context (like a Vue 3 frontend with a Laravel backend). That's what i found :

    In the AbstractProvider.php class, the redirect() method includes this code:

    public function redirect()
    {
        $state = null;
        if ($this->usesState()) {
            $this->request->session()->put('state', $state = $this->getState());
        }
        if ($this->usesPKCE()) {
            $this->request->session()->put('code_verifier', $this->getCodeVerifier());
        }
        return new RedirectResponse($this->getAuthUrl($state));
    }
    

    This method checks if PKCE (Proof Key for Code Exchange) is used via the usesPKCE() method:

    protected function usesPKCE()
    {
        return $this->usesPKCE;
    }
    

    In the TwitterProvide.php class, which extends AbstractProvider, the $usesPKCE property is always set to true

    class TwitterProvider extends AbstractProvider implements ProviderInterface
    {
        /**
         * The scopes being requested.
         *
         * @var array
         */
        protected $scopes = ['users.read', 'tweet.read'];
    
        /**
         * Indicates if PKCE should be used.
         *
         * @var bool
         */
        protected $usesPKCE = true;
    
        /**
         * The separating character for the requested scopes.
         *
         * @var string
         */
        protected $scopeSeparator = ' ';
    
        /**
         * The query encoding format.
         *
         * @var int
         */
        protected $encodingType = PHP_QUERY_RFC3986;
    

    This means that even when you set the provider to stateless, it will still attempt to store the code verifier in the session. In an API context, where sessions aren't typically used, this leads to a "session is not defined" error.

    This is why I had to implement my own custom method to handle the Twitter provider in this stateless, API-based scenario.


  2. You’ll need to use the web middleware if you need session state, CSRF protection.

    Your routes should go inside the web middleware as shown below:

    Route::group(['middleware' => ['web']], function () {
        // your routes here
    });
    

    If the above solution doesn’t work then try adding this to $middleware into Kernel.php

    protected $middleware = [
            IlluminateSessionMiddlewareStartSession::class,
            IlluminateViewMiddlewareShareErrorsFromSession::class,
    ];
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search