Laravel 5 and Socialite - New Redirect After Login

2019-02-24 09:09发布

问题:

Another newb question here, but hopefully someone can shed some light:

I am using Socialite with Laravel 5, and I want to be able to redirect the user to a page on the site after they have logged in. The problem is that using

return redirect('any-path-I-put-here');

simply redirects back to 'social-site/login?code=afkjadfkjdslkfjdlkfj...' (where 'social-site' is whatever site is being used i.e. facebook, twitter, google, etc.)

So, what appears to me to be happening is that the redirect() function in the Socialite/Contracts/Provider interface is overriding any redirect that I attempt after the fact.

Just for clarification, my routes are set up properly. I have tried every version of 'redirect' you can imagine ('to', 'back', 'intended', Redirect::, etc.), and the method is being called from my Auth Controller (though I have tried it elsewhere as well).

The question is, how do I override that redirect() once I am done storing and logging in the user with socialite? Any help is appreciated! Thank you in advance.

The code that contains the redirect in question is:

public function socialRedirect( $route, $status, $greeting, $user )
{

    $this->auth->login( $user, true );

    if( $status == 'new_user' ) {
        // This is a new member. Make sure they see the welcome modal on redirect
        \Session::flash( 'new_registration', true );

        return redirect()->to( $route );// This is just the most recent attempt. It originated with return redirect($route);, and has been attempted every other way you can imagine as well (as mentioned above). Hardcoding (i.e., 'home') returns the exact same result. The socialite redirect always overrides anything that is put here.
    }
    else {
        return redirect()->to( $route )->with( [ 'greeting' => $greeting ] );
    }
}

... The SocialAuth class that runs before this, however, is about 500 lines long, as it has to determine if the user exists, register new users if necessary, show forms for different scenarios, etc. Meanwhile, here is the function that sends the information through from the Social Auth class:

private function socialLogin( $socialUser, $goto, $provider, $status, $controller )
{
    if( is_null( $goto ) ) {
        $goto = 'backlot/' . $socialUser->profile->custom_url;
    }

    if( $status == 'new_user' ) {
        return $controller->socialRedirect($goto, $status, null, $socialUser);
    }
    else {
        // This is an existing member. Show them the welcome back status message.
        $message = 'You have successfully logged in with your ' .
            ucfirst( $provider ) . ' credentials.';

        $greeting =
            flash()->success( 'Welcome back, ' . $socialUser->username . '. ' . $message );

        return $controller->socialRedirect($goto, $status, $greeting, $socialUser);
    }
}

回答1:

I believe you are overthinking this. Using Socialite is pretty straight forward:

Set up config/services.php. For facebook I have this:

 'facebook' => [
    'client_id' => 'your_fb_id',
    'client_secret' => 'your_fb_secret',
    'redirect' => '>ABSOLUTE< url to redirect after login', //like: 'http://stuff'
  ],

Then set up two routes, one for login and one for callback (after login).

In the login controller method:

return \Socialize::with('facebook')->redirect();

Then in the callback function

$fb_user = \Socialize::with('facebook')->user();
// check if user exists, create it and whatnot
//dd($fb_user);
return redirect()->route('some.route');

For more detail check this: http://www.codeanchor.net/blog/complete-laravel-socialite-tutorial/

It should be pretty much similar for all other providers.



回答2:

I managed to workaround this problem, but I am unsure if this is the best way to fix it. Similar to what is stated in question, I got authenticated callback from the social media, but I was unable to redirect current response to another url.

Based on the callback request params, I was able to create and authenticate the user within my Laravel app. It worked good so far but the problems occured after this step when I tried to do a return redirect()->route('dashboard');. I tried all the flavours of redirect() helper and Redirect facade but nothing helped.

The blank page just stared at my face for over 2 days, before I checked this question. The behaviour was very similar. I got redirect from social-media to my app but could not further redirect in the same response cycle.

At this moment (when the callback was recieved by the app and user was authenticated), if I refreshed the page manually (F5), I got redirected to the intended page. My interpretation is similar to what's stated in this question earlier. The redirect from social-media callback was dominating the redirects I was triggering in my controller (May be redirect within Laravel app got suppressed because the redirect from social-media was still not complete). It's just my interpretation. Experts can throw more light if they think otherwise or have a better explaination.

To fix this I issued a raw http redirect using header("Location /dashboard"); and applied auth middleware to this route. This way I could mock the refresh functionality ,redirect to dashboard (or intended url) and check for authentication in my DashboardController.

Once again, this is not a perfect solution and I am investigating the actual root of the problem, but this might help you to move ahead if you are facing similar problem.



回答3:

We are using the Socialite login in our UserController as a trait. We simply overrode the AuthenticatesSocialiteLogin::loginSuccess() in our controller.

use Broco\SocialiteLogin\Auth\AuthenticatesSocialiteLogin;

class UserController extends BaseController
{
    use AuthenticatesSocialiteLogin;

    public function loginSuccess($user)
    {
        return redirect()->intended(url('/#login-success'));
    }

....