diadal/vue-social-auth

Twitter provider pinging /auth/twitter causing 404

Closed this issue · 6 comments

I have this working fine with the facebook and github providers, but when I try using twitter I get a 404 that's pointing to my website URL follow by /auth/twitter just before it brings up the popup (popup is just showing about:blank and not changing).

None of the other providers seem to do this, and looking at the source code it looks like twitter is the only provider setup to still use oauth 1 instead of oauth 2.

check the vue route and the spelling

None of the other providers seem to do this, and looking at the source code it looks like twitter is the only provider setup to still use oauth 1 instead of oauth 2

I will check this later busy a lot with other project or you can submit the PR

wuori commented

@Truemedia I finally figured this out after two nights of hammering at it.

Pros: Can work without updates/PRs to vue-social-auth
Cons: Requires separate endpoint/method for handling twitter in your Auth controller.

My app requires this be done stateless which made it extra painful, so I'll leave that part out of this until I can make a PR to Socialite's Twitter driver.

Steps I took to make it work:

In the config for vue-social-auth:

twitter: {
      clientId: 'twitterclientID',
      redirectUri: 'https://localhost:8081/auth/twitter/callback',
      url: 'https://api.whatever.test/auth/twitter', // instead of /auth/twitter
      responseParams: {
        oauth_token: 'oauth_token',
      }
},

I left the default url as /auth/twitter and added the route:

Route::post('auth/twitter', 'Auth\AuthController@twitter');

The code below is NASTY and I'm hoping my PR will make this a lot cleaner

The vue plugin calls the same path /auth/twitter for both the initial token AND the access token, so I have them both in the same method for now.

Since the code for retrieving the initial token isn't exposed via method, I'm grabbing it from the actual redirect Response object.

If you don't require stateless, you can just use the one line below instead of the "get oauthtoken from response" bit below

Again, hacky but I plan on cleaning it up and submitting some PRs.

Socialite::with('twitter')->stateless()->redirect();

public function twitter(Request $request)
{
        if ($request->oauth_verifier) {
            $this->provider = 'twitter';
            $this->user_data = Socialite::driver('twitter')->stateless()->user()
            return response()->json($this->user_data);
        }

        // get oauthtoken from response
        $token = Socialite::with('twitter')->stateless()->redirect();
        $response = print_r($token, true);
        $regex = '/https?\:\/\/[^\" ]+/i';
        preg_match($regex, $response, $matches);

        // handle URL if found
        $url = $matches[0] ?? null;
        if (!$url) {
            abort(404);
        }
        $token = explode('=', trim($url));
        $token = $token[1];

        return response()->json(['oauth_token' => $token]);
    }

I'll comment on this thread again as I make progress on making this a more legit solution, but if you're as frustrated as I am (and apparently everyone else on StackOverflow) then hopefully this can help you get past a few headaches until a better solution is reached.

I'm sure implementing this in a system where cookies/session is available will be a lot easier, but, like I mentioned, I needed mine to be completely stateless as the app is all api-driven and the headache of making cookies work across all environments is a PITA.

I hope this helps!

@wuori Thanks for looking into it I did run out of time to get much further. I'll wait for PR to try myself as don't need urgently but nice to have when I know will work cleanly like the other providers I'm using

wuori commented

Update for anybody following this issue:

I've created a PR for an additional method in the Socialite provider that is required to implement Twitter Oauth1 for a stateless application.

If/when it is approved/merged I'll create another PR for this repo to add the additional functionality needd for this to work out of the box.

You can add the serverMiddleware for a handle this if u are using NUXT