Skip to content

feat: add the foundation for OAuth2 with Laravel Passport#4164

Merged
wescopeland merged 29 commits intoRetroAchievements:masterfrom
m1guelpf:oauth2
Dec 8, 2025
Merged

feat: add the foundation for OAuth2 with Laravel Passport#4164
wescopeland merged 29 commits intoRetroAchievements:masterfrom
m1guelpf:oauth2

Conversation

@m1guelpf
Copy link
Copy Markdown
Contributor

@m1guelpf m1guelpf commented Nov 24, 2025

How to test this PR

Adds OAuth2 authentication using Laravel Passport!

Current state of things:

  • The end-to-end flow works!
  • The end-to-end flow for device authentication works!
  • There is no UI to create clients, use php artisan passport:client and php artisan passport:client --device for testing.
  • There is no UI to revoke authorizations
  • All the routes are disabled in production

edited by @wescopeland to update the current state of things and directly link to my comment

@wescopeland
Copy link
Copy Markdown
Member

I collaborated heavily on this PR.

How to test this PR

sail artisan migrate
sail artisan passport:keys # this is already done on stage and prod

There are two authorization flows you can test-drive. The first is a standard client authorization flow where some app wants to log in on behalf of a user:

# Create a test OAuth client
# name: "SampleApp"
# redirect: [default] "http://localhost:64000/auth/callback"
# device auth? "no"
sail artisan passport:client

You'll receive a Client ID and Client Secret.

Navigate to:
http://localhost:64000/oauth/authorize?client_id={CLIENT_ID}&redirect_uri=http://localhost:64000/auth/callback&response_type=code

Screenshot 2025-11-25 at 6 36 42 PM

In the real world, clicking Authorize and Reject will direct back to the consumer app. In our demo, we have an /auth/callback dummy route set up to simulate an end-to-end authorization flow.

The other supported authorization flow is the device flow:

# This time, on the device auth question, answer "yes"
sail artisan passport:client

# Now, initiate the device flow.
curl -X POST http://localhost:64000/oauth/device/code \
  -d "client_id={CLIENT_ID}"

In the response, you'll see an 8-character user_code. Copy that value, and navigate to http://localhost:64000/oauth/device.

Screenshot 2025-11-25 at 6 39 13 PM

Here, you can enter the 8-character code. Upon doing that, you'll see an Approve and Reject button again. Click either, and you'll see a confirmation. In the real-world, the user's app is going to be polling for the approve/reject status.

Screenshot 2025-11-25 at 6 41 03 PM Screenshot 2025-11-25 at 6 41 08 PM

@wescopeland wescopeland marked this pull request as ready for review November 25, 2025 23:42
@wescopeland wescopeland changed the title wip: OAuth2 with Passport feat: add the foundation for OAuth2 with Laravel Passport Nov 25, 2025
@wescopeland wescopeland requested a review from a team November 25, 2025 23:47
Copy link
Copy Markdown
Member

@Jamiras Jamiras left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as the user is logged in, things seem to work appropriately. Left a couple comments regarding the flow when not logged in, and a general question on what the next steps would look like.

Comment thread database/migrations/2025_11_24_000001_create_oauth_tables.php Outdated
Comment thread resources/js/features/auth/components/+authorize/AuthorizeRoot.tsx
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entering the correct credentials opens the form in a popup window where the code has to be entered again.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check in latest if you're still seeing this - I wasn't while authenticated.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not. And if it wasn't clear - this was hitting the page in an incognito mode, which would require logging in after entering the code. Then it would prompt to enter the code again after logging in. Putting the login before the code addresses the issue.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appears to be fixed.

Similar to other comment: "Entering the correct credentials" implies doing this while not authenticated.

Comment thread app/Providers/RouteServiceProvider.php
Comment thread app/Providers/RouteServiceProvider.php
Copilot AI review requested due to automatic review settings December 6, 2025 02:54

This comment was marked as spam.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not. And if it wasn't clear - this was hitting the page in an incognito mode, which would require logging in after entering the code. Then it would prompt to enter the code again after logging in. Putting the login before the code addresses the issue.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appears to be fixed.

Similar to other comment: "Entering the correct credentials" implies doing this while not authenticated.

@wescopeland wescopeland merged commit 9ef58ca into RetroAchievements:master Dec 8, 2025
13 checks passed
@m1guelpf m1guelpf deleted the oauth2 branch December 8, 2025 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants