Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Laravel Passport authorization flow not working with Inertia? #303

Closed
abbluiz opened this issue Sep 20, 2021 · 6 comments
Closed

Laravel Passport authorization flow not working with Inertia? #303

abbluiz opened this issue Sep 20, 2021 · 6 comments
Labels
wontfix This will not be worked on

Comments

@abbluiz
Copy link

abbluiz commented Sep 20, 2021

When Laravel Passport redirects back to an external URI after the OAuth 2.0 authorization flow, it renders an iframe of the external website, instead of actually redirecting to the external website.

@abbluiz abbluiz changed the title Laravel Passport redirect flow not working with Inertia? Laravel Passport authorization flow not working with Inertia? Sep 20, 2021
@abbluiz
Copy link
Author

abbluiz commented Sep 20, 2021

The thing is I could use Inertia::location($url) to redirect to the external client URL, but this is internal of Passport. The workaround I found was to override the handle method in HandleInertiaRequests.php:

    public function handle(Request $request, Closure $next)
    {
        $parentResponse = parent::handle($request, $next);

        if (!empty($request->redirect_uri)) {
            return Inertia::location($parentResponse->headers->all()['location'][0]);
        }

        return $parentResponse;
    }

It checks if the request had an request_uri; there should probably be a better condition to test this, though.

@tranelearth
Copy link

tranelearth commented Oct 8, 2021

This solution partially worked for me while using Token Grant OAuth. Ultimately, I had to create a Blade login form (and controller), and add the following to app/Exceptions/Handler.php:

protected function unauthenticated($request, \Illuminate\Auth\AuthenticationException $exception)
    {
        if ($request->expectsJson()) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }

        if ($request->response_type === 'code') {
            return redirect()->guest(route('oAuth-login-form-route'));
        }

        return redirect()->route('login');
    }

@abbluiz
Copy link
Author

abbluiz commented Oct 14, 2021

@tranelearth Interesting. I wonder whether there should be more compatibility between Inertia and Passport, and whether they are tested together or not at all.

@abbluiz
Copy link
Author

abbluiz commented Dec 14, 2021

I have updated my middleware. It is easier to understand now:

public function handle(Request $request, Closure $next)
{
    $parentResponse = parent::handle($request, $next);

    $location = $parentResponse->headers->get('Location');

    if ($this->isExternal($location)) {
        if (request()->inertia()) {
            return inertia()->location($location);
        }

        return redirect()->to($location);
    }

    return $parentResponse;
}

A method to check if an URL is external, which is used above:

public function isExternal($url)
{
    $internalHost = parse_url(config('app.url'), PHP_URL_HOST);
    $internalPort = parse_url(config('app.url'), PHP_URL_PORT);

    $host = parse_url($url, PHP_URL_HOST);
    $port = parse_url($url, PHP_URL_PORT);

    return $host !== $internalHost || $port !== $internalPort;
}

@claudiodekker
Copy link
Member

claudiodekker commented Dec 24, 2021

Hey @abbluiz, thanks for reporting this issue.

Whether Inertia is compatible with Passport or any third-party library really depends on the third-party library for the most part, as Inertia in and by itself is just a generic library. However, I'll leave this issue open so that we can investigate and perhaps come up with a fix for this Passport-specific issue somewhere later.

My personal approach to this would probably be to add a special route that uses Inertia::location() to redirect to the Passport OAuth route. That way, you immediately (as the first step in the chain) tell Inertia that we're no longer using Inertia going forward, allowing Passport to properly render it's routes/do it's thing. Then afterwards, you can make sure it redirects back to your Inertia pages.

Hope this helps!

@claudiodekker claudiodekker added the wontfix This will not be worked on label Dec 24, 2021
@claudiodekker claudiodekker moved this to New 📑 in Inertia.js Jan 4, 2022
@jessarcher
Copy link
Member

Hey there,

We're closing this issue because it's inactive, already solved, old or not relevant anymore. Feel free to open up a new issue if you're still experiencing this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
Status: Closed 🚪
Development

No branches or pull requests

4 participants