Rey777
Rey777

Reputation: 109

Laravel 8 SSO implementation

I am tring to implement a SSO structure:

I managed to make the base login with sso-app api using Laravel Passport package. Here the app1 controller for the authorization process:

class SSOController extends Controller
{

public function getLogin(Request $request){
    $request->session()->put("state", $state = Str::random(40));
    $query = http_build_query([
        'client_id' => env('SSO_CLIENT_ID'),
        'redirect_uri' => env('APP_URL') . '/auth/callback',
        'response_type' => 'code',
        'scope' => '',
        'state' => $state
    ]);

    return redirect(env('SSO_HOST') . '/oauth/authorize?' . $query);
}

public function getCallback(Request $request){
    $state = $request->session()->pull('state');

    throw_unless(strlen($state) > 0 && $state == $request->state, 
        InvalidArgumentException::class
    );

    $response = Http::asForm()->post(
        env('SSO_HOST') . '/oauth/token',
        [
            'grant_type' => 'authorization_code',
            'client_id' => env('SSO_CLIENT_ID'),
            'client_secret' => env('SSO_SECRET'),
            'redirect_uri' => env('APP_URL') . '/auth/callback',
            'code' => $request->code
        ]
    );

    $request->session()->put($response->json());

    $token = $response->json()['access_token'];

    
    $jwtHeader = null;
    $jwtPayload = null;
    $parsed_token = parse_jwt($token);

    
    try{
        $email = $parsed_token->payload->user->email;
    }
    catch(\Throwable $e){
        return redirect('login')->withError("Failed to get login information! Try again.");
    }
    
    $user = User::firstOrCreate(['email' => $email], array_merge((array)$parsed_token->payload->user, ['name' => ($parsed_token->payload->user->first_name." ".$parsed_token->payload->user->last_name)]));

    Auth::login($user);

    return redirect(route('home'));
    
}
}

The app1 will redirect to sso-app login form than when user successfull login he will redirect back to app1.

Everything work as aspected, but how can I use this approach to authorize the api route?

This work only for the "web" guard because I had create a local user table for every app and made the login based on session as you can see on the end of SSOController.

But how can I use the token returned from sso-app to authenticate local app1, app2, ... api? Should I have to create a middleware that call sso-app every time I call app1 api to check if the token is valid or there is a better approach to save time and increase speed?

Thanks.

Upvotes: 0

Views: 2302

Answers (0)

Related Questions