Skip to content

Commit 46b107e

Browse files
committed
refactor: consistency changes
1 parent d2cdea9 commit 46b107e

18 files changed

+74
-134
lines changed

docs/2-features/17-oauth.md

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
---
22
title: OAuth
3-
description: "Tempest's OAuth provides a way to authenticate users with many different OAuth providers, such as GitHub, Google, Discord, and many others."
3+
description: "Learn how to implement OAuth to authenticate users with many different providers, such as GitHub, Google, Discord, and many others."
44
keywords: "Experimental"
55
---
66

77
## Overview
88

99
Tempest provides the ability to authenticate users with many OAuth providers, such as GitHub, Google, Discord, and many others, using the same interface.
1010

11-
This implementation is built on top of [OAuth 2.0 Client](https://github.com/thephpleague/oauth2-client)—a reliable, battle-tested OAuth 2.0 client library.
11+
This implementation is built on top of the PHP league's [OAuth client](https://github.com/thephpleague/oauth2-client)—a reliable, battle-tested OAuth 2.0 client library.
1212

1313
## Getting started
1414

1515
To get started with OAuth, you will first need to create a configuration file for your desired OAuth provider.
1616

17-
Tempest provides a different configuration object for each provider. For instance, if you wish to authenticate users with GitHub, you may create a `github.config.php` file returning an instance of {b`Tempest\Auth\OAuth\Config\GitHubOAuthConfig`}:
17+
Tempest provides a [different configuration object for each provider](#available-providers). For instance, if you wish to authenticate users with GitHub, you may create a `github.config.php` file returning an instance of {b`Tempest\Auth\OAuth\Config\GitHubOAuthConfig`}:
1818

1919
```php app/Auth/github.config.php
2020
return new GitHubOAuthConfig(
2121
clientId: env('GITHUB_CLIENT_ID'),
2222
clientSecret: env('GITHUB_CLIENT_SECRET'),
23-
redirectUri: [GitHubOAuthController::class, 'callback'],
23+
redirectTo: [GitHubOAuthController::class, 'callback'],
2424
scopes: ['user:email'],
2525
);
2626
```
@@ -31,58 +31,67 @@ Once your OAuth provider is configured, you may interact with it by using the {`
3131

3232
## Implementing the OAuth flow
3333

34-
To implement a complete OAuth flow for your application, you will need to use the {b`Tempest\Auth\OAuth\OAuthClient`} interface to redirect the user to the OAuth provider's authorization page, and fetch the user's information in the controller action to which the OAuth provider redirects back.
34+
To implement a complete OAuth flow for your application, you will need two routes.
3535

36-
The following is an example of a full OAuth flow, including CSRF protection, saving or updating the user, and authenticating them against the application:
36+
- The first one will redirect the user to the OAuth provider's authorization page,
37+
- The second one, which will be redirected to once the user authorizes your application, will fetch the user's information thanks to the code provided by the OAuth provider.
3738

38-
```php app/Auth/GitHubOAuthController.php
39+
The {b`Tempest\Auth\OAuth\OAuthClient`} interface has the necessary methods to handle both parts of the flow. The following is an example of a complete OAuth flow, including CSRF protection, creating or updating the user, and authenticating them against the application:
40+
41+
```php app/Auth/DiscordOAuthController.php
3942
use Tempest\Auth\OAuth\OAuthClient;
4043

41-
final readonly class GitHubOAuthController
44+
final readonly class DiscordOAuthController
4245
{
4346
public function __construct(
4447
private OAuthClient $oauth,
4548
private Session $session,
4649
private Authenticator $authenticator,
4750
) {}
4851

49-
#[Get('/auth/github')]
52+
#[Get('/auth/discord')]
5053
public function redirect(): Redirect
5154
{
52-
$this->session->set('github:oauth', $this->oauth->getState());
55+
// Saves a unique token in the user's session
56+
$this->session->set('discord:oauth', $this->oauth->getState());
5357

58+
// Redirects to the OAuth provider's authorization page
5459
return new Redirect($this->oauth->getAuthorizationUrl());
5560
}
5661

57-
#[Get('/auth/github/callback')]
62+
#[Get('/auth/discord/callback')]
5863
public function callback(Request $request): Redirect
5964
{
60-
if ($this->session->get('github:oauth') !== $request->get('state')) {
65+
// Validates the saved session token to prevent CSRF attacks
66+
if ($this->session->get('discord:oauth') !== $request->get('state')) {
6167
return new Redirect('/?error=invalid_state');
6268
}
6369

64-
$githubUser = $this->oauth->fetchUser($request->get('code'));
70+
// Fetches the user information from the OAuth provider
71+
$discordUser = $this->oauth->fetchUser($request->get('code'));
6572

73+
// Creates or updates the user in the database
6674
$user = query(User::class)->updateOrCreate([
67-
'discord_id' => $githubUser->id,
75+
'discord_id' => $discordUser->id,
6876
], [
69-
'discord_id' => $githubUser->id,
70-
'username' => $githubUser->nickname,
71-
'email' => $githubUser->email,
77+
'discord_id' => $discordUser->id,
78+
'username' => $discordUser->nickname,
79+
'email' => $discordUser->email,
7280
]);
7381

82+
// Finally, authenticates the user in the application
7483
$this->authenticator->authenticate($user);
7584

7685
return new Redirect('/');
7786
}
7887
}
7988
```
8089

81-
Of course, this example assumes that an [authenticatable model](../2-features/04-authentication.md#authentication) is configured.
90+
Of course, this example assumes that the database and an [authenticatable model](../2-features/04-authentication.md#authentication) are configured.
8291

8392
### Working with the OAuth user
8493

85-
When an OAuth flow is completed, you will receive an {b`Tempest\Auth\OAuth\OAuthUser`} object containing the user's information from the OAuth provider:
94+
When an OAuth flow is completed and you call `fetchUser`, you will receive an {b`Tempest\Auth\OAuth\OAuthUser`} object containing the user's information from the OAuth provider:
8695

8796
```php
8897
$user = $this->oauth->fetchUser($code);
@@ -100,18 +109,18 @@ As seen in the example above, you can use this information to create or update a
100109

101110
## Configuring a provider
102111

103-
Most providers require only a `clientId`, `clientSecret` and `redirectUri`, but some might need other parameters. A typical configuration looks like the following:
112+
Most providers require only a `clientId`, `clientSecret` and `redirectTo`, but some might need other parameters. A typical configuration looks like the following:
104113

105114
```php app/Auth/github.config.php
106115
return new GitHubOAuthConfig(
107116
clientId: env('GITHUB_CLIENT_ID'),
108117
clientSecret: env('GITHUB_CLIENT_SECRET'),
109-
redirectUri: [GitHubOAuthController::class, 'callback'],
118+
redirectTo: [GitHubOAuthController::class, 'callback'],
110119
scopes: ['user:email'],
111120
);
112121
```
113122

114-
Note that the `redirectUri` accepts a tuple of a controller class and a method name, which will be resolved to the full URL of the route handled by that method. You may also provide an URI path if you prefer.
123+
Note that the `redirectTo` accepts a tuple of a controller class and a method name, which will be resolved to the full URL of the route handled by that method. You may also provide an URI path if you prefer.
115124

116125
### Supporting multiple providers
117126

@@ -133,7 +142,7 @@ return new GitHubOAuthConfig(
133142
tag: Provider::GITHUB,
134143
clientId: env('GITHUB_CLIENT_ID'),
135144
clientSecret: env('GITHUB_CLIENT_SECRET'),
136-
redirectUri: [OAuthController::class, 'handleGitHubCallback'],
145+
redirectTo: [OAuthController::class, 'handleGitHubCallback'],
137146
scopes: ['user:email'],
138147
);
139148
```
@@ -143,7 +152,7 @@ return new GoogleOAuthConfig(
143152
tag: Provider::GOOGLE,
144153
clientId: env('GOOGLE_CLIENT_ID'),
145154
clientSecret: env('GOOGLE_CLIENT_SECRET'),
146-
redirectUri: [GoogleOAuthController::class, 'handleGoogleCallback'],
155+
redirectTo: [GoogleOAuthController::class, 'handleGoogleCallback'],
147156
);
148157
```
149158

@@ -189,7 +198,7 @@ If you need to implement OAuth with a provider that Tempest doesn't have a speci
189198
return new GenericOAuthConfig(
190199
clientId: env('CUSTOM_CLIENT_ID'),
191200
clientSecret: env('CUSTOM_CLIENT_SECRET'),
192-
redirectUri: [OAuthController::class, 'handleCallback'],
201+
redirectTo: [OAuthController::class, 'handleCallback'],
193202
urlAuthorize: 'https://provider.com/oauth/authorize',
194203
urlAccessToken: 'https://provider.com/oauth/token',
195204
urlResourceOwnerDetails: 'https://provider.com/api/user',
@@ -266,7 +275,7 @@ final class OAuthControllerTest extends IntegrationTestCase
266275
// with the same fake code we provided before
267276
$oauth->assertUserFetched(code: 'some-fake-code');
268277

269-
// Finally, we ensure an user was created with the
278+
// Finally, we ensure a user was created with the
270279
// credentials we specified in the fake OAuth user
271280
$user = query(User::class)
272281
->find(discord_id: 'jon')

packages/auth/src/OAuth/Config/AppleOAuthConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function __construct(
4040
/**
4141
* The redirect URI for the OAuth flow.
4242
*/
43-
public string|array $redirectUri,
43+
public string|array $redirectTo,
4444

4545
/**
4646
* The scopes to request from Apple.

packages/auth/src/OAuth/Config/DiscordOAuthConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public function __construct(
2828
public string $clientSecret,
2929

3030
/**
31-
* The redirect URI for the OAuth flow.
31+
* The controller action to redirect to after the user authorizes the application.
3232
*/
33-
public string|array $redirectUri,
33+
public string|array $redirectTo,
3434

3535
/**
3636
* The scopes to request from Discord.

packages/auth/src/OAuth/Config/FacebookOAuthConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public function __construct(
2828
public string $clientSecret,
2929

3030
/**
31-
* The redirect URI for the OAuth flow.
31+
* The controller action to redirect to after the user authorizes the application.
3232
*/
33-
public string|array $redirectUri,
33+
public string|array $redirectTo,
3434

3535
/**
3636
* The scopes to request from Facebook.

packages/auth/src/OAuth/Config/GenericOAuthConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public function __construct(
2828
public string $clientSecret,
2929

3030
/**
31-
* The redirect URI for the OAuth flow.
31+
* The controller action to redirect to after the user authorizes the application.
3232
*/
33-
public string|array $redirectUri,
33+
public string|array $redirectTo,
3434

3535
/**
3636
* The authorization URL for the OAuth provider.

packages/auth/src/OAuth/Config/GitHubOAuthConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ public function __construct(
2929
public string $clientSecret,
3030

3131
/**
32-
* The redirect URI for the OAuth flow.
32+
* The controller action to redirect to after the user authorizes the application.
3333
*/
34-
public string|array $redirectUri,
34+
public string|array $redirectTo,
3535

3636
/**
3737
* The scopes to request from GitHub.

packages/auth/src/OAuth/Config/GoogleOAuthConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ public function __construct(
2929
public string $clientSecret,
3030

3131
/**
32-
* The redirect URI for the OAuth flow.
32+
* The controller action to redirect to after the user authorizes the application.
3333
*/
34-
public string|array $redirectUri,
34+
public string|array $redirectTo,
3535

3636
/**
3737
* The scopes to request from Google.

packages/auth/src/OAuth/Config/InstagramOAuthConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public function __construct(
2828
public string $clientSecret,
2929

3030
/**
31-
* The redirect URI for the OAuth flow.
31+
* The controller action to redirect to after the user authorizes the application.
3232
*/
33-
public string|array $redirectUri,
33+
public string|array $redirectTo,
3434

3535
/**
3636
* The scopes to request from Instagram.

packages/auth/src/OAuth/Config/LinkedInOAuthConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public function __construct(
2828
public string $clientSecret,
2929

3030
/**
31-
* The redirect URI for the OAuth flow.
31+
* The controller action to redirect to after the user authorizes the application.
3232
*/
33-
public string|array $redirectUri,
33+
public string|array $redirectTo,
3434

3535
/**
3636
* The scopes to request from LinkedIn.

packages/auth/src/OAuth/Config/MicrosoftOAuthConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public function __construct(
2828
public string $clientSecret,
2929

3030
/**
31-
* The redirect URI for the OAuth flow.
31+
* The controller action to redirect to after the user authorizes the application.
3232
*/
33-
public string|array $redirectUri,
33+
public string|array $redirectTo,
3434

3535
/**
3636
* The scopes to request from Microsoft.

0 commit comments

Comments
 (0)