Skip to content

Commit 0a27f42

Browse files
committed
pre socialite
1 parent 4336c96 commit 0a27f42

30 files changed

Lines changed: 1661 additions & 6 deletions
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
name: socialite-development
3+
description: "Manages OAuth social authentication with Laravel Socialite. Activate when adding social login providers; configuring OAuth redirect/callback flows; retrieving authenticated user details; customizing scopes or parameters; setting up community providers; testing with Socialite fakes; or when the user mentions social login, OAuth, Socialite, or third-party authentication."
4+
license: MIT
5+
metadata:
6+
author: laravel
7+
---
8+
9+
# Socialite Authentication
10+
11+
## Documentation
12+
13+
Use `search-docs` for detailed Socialite patterns and documentation (installation, configuration, routing, callbacks, testing, scopes, stateless auth).
14+
15+
## Available Providers
16+
17+
Built-in: `facebook`, `twitter`, `twitter-oauth-2`, `linkedin`, `linkedin-openid`, `google`, `github`, `gitlab`, `bitbucket`, `slack`, `slack-openid`, `twitch`
18+
19+
Community: 150+ additional providers at [socialiteproviders.com](https://socialiteproviders.com). For provider-specific setup, use `WebFetch` on `https://socialiteproviders.com/{provider-name}`.
20+
21+
Configuration key in `config/services.php` must match the driver name exactly — note the hyphenated keys: `twitter-oauth-2`, `linkedin-openid`, `slack-openid`.
22+
23+
Twitter/X: Use `twitter-oauth-2` (OAuth 2.0) for new projects. The legacy `twitter` driver is OAuth 1.0. Driver names remain unchanged despite the platform rebrand.
24+
25+
Community providers differ from built-in providers in the following ways:
26+
- Installed via `composer require socialiteproviders/{name}`
27+
- Must register via event listener — NOT auto-discovered like built-in providers
28+
- Use `search-docs` for the registration pattern
29+
30+
## Adding a Provider
31+
32+
### 1. Configure the provider
33+
34+
Add the provider's `client_id`, `client_secret`, and `redirect` to `config/services.php`. The config key must match the driver name exactly.
35+
36+
### 2. Create redirect and callback routes
37+
38+
Two routes are needed: one that calls `Socialite::driver('provider')->redirect()` to send the user to the OAuth provider, and one that calls `Socialite::driver('provider')->user()` to receive the callback and retrieve user details.
39+
40+
### 3. Authenticate and store the user
41+
42+
In the callback, use `updateOrCreate` to find or create a user record from the provider's response (`id`, `name`, `email`, `token`, `refreshToken`), then call `Auth::login()`.
43+
44+
### 4. Customize the redirect (optional)
45+
46+
- `scopes()` — merge additional scopes with the provider's defaults
47+
- `setScopes()` — replace all scopes entirely
48+
- `with()` — pass optional parameters (e.g., `['hd' => 'example.com']` for Google)
49+
- `asBotUser()` — Slack only; generates a bot token (`xoxb-`) instead of a user token (`xoxp-`). Must be called before both `redirect()` and `user()`. Only the `token` property will be hydrated on the user object.
50+
- `stateless()` — for API/SPA contexts where session state is not maintained
51+
52+
### 5. Verify
53+
54+
1. Config key matches driver name exactly (check the list above for hyphenated names)
55+
2. `client_id`, `client_secret`, and `redirect` are all present
56+
3. Redirect URL matches what is registered in the provider's OAuth dashboard
57+
4. Callback route handles denied grants (when user declines authorization)
58+
59+
Use `search-docs` for complete code examples of each step.
60+
61+
## Additional Features
62+
63+
Use `search-docs` for usage details on: `enablePKCE()`, `userFromToken($token)`, `userFromTokenAndSecret($token, $secret)` (OAuth 1.0), retrieving user details.
64+
65+
User object: `getId()`, `getName()`, `getEmail()`, `getAvatar()`, `getNickname()`, `token`, `refreshToken`, `expiresIn`, `approvedScopes`
66+
67+
## Testing
68+
69+
Socialite provides `Socialite::fake()` for testing redirects and callbacks. Use `search-docs` for faking redirects, callback user data, custom token properties, and assertion methods.
70+
71+
## Common Pitfalls
72+
73+
- Config key must match driver name exactly — hyphenated drivers need hyphenated keys (`linkedin-openid`, `slack-openid`, `twitter-oauth-2`). Mismatch silently fails.
74+
- Every provider needs `client_id`, `client_secret`, and `redirect` in `config/services.php`. Missing any one causes cryptic errors.
75+
- `scopes()` merges with defaults; `setScopes()` replaces all scopes entirely.
76+
- Missing `stateless()` in API/SPA contexts causes `InvalidStateException`.
77+
- Redirect URL in `config/services.php` must exactly match the provider's OAuth dashboard (including trailing slashes and protocol).
78+
- Do not pass `state`, `response_type`, `client_id`, `redirect_uri`, or `scope` via `with()` — these are reserved.
79+
- Community providers require event listener registration via `SocialiteWasCalled`.
80+
- `user()` throws when the user declines authorization. Always handle denied grants.

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This application is a Laravel application and its main Laravel ecosystems packag
1515
- laravel/framework (LARAVEL) - v13
1616
- laravel/prompts (PROMPTS) - v0
1717
- laravel/sanctum (SANCTUM) - v4
18+
- laravel/socialite (SOCIALITE) - v5
1819
- laravel/wayfinder (WAYFINDER) - v0
1920
- laravel/boost (BOOST) - v2
2021
- laravel/mcp (MCP) - v0

app/Models/Social.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Attributes\Fillable;
6+
use Illuminate\Database\Eloquent\Factories\HasFactory;
7+
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
9+
10+
#[Fillable(['user_id', 'provider', 'provider_id', 'avatar'])]
11+
class Social extends Model
12+
{
13+
use HasFactory;
14+
15+
public function user(): BelongsTo
16+
{
17+
return $this->belongsTo(User::class);
18+
}
19+
20+
public function isProvider(string $provider): bool
21+
{
22+
return $this->provider === $provider;
23+
}
24+
}

app/Models/User.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,22 @@ public function registries(): HasMany
2727
return $this->hasMany(Registry::class);
2828
}
2929

30+
public function hasLinkedProvider(string $provider): bool
31+
{
32+
return $this->socials()->where('provider', $provider)->exists();
33+
}
34+
35+
36+
public function socials(): HasMany
37+
{
38+
return $this->hasMany(Social::class);
39+
}
40+
41+
public function connectedAccounts(): HasMany
42+
{
43+
return $this->socials();
44+
}
45+
3046
/**
3147
* Get the attributes that should be cast.
3248
*

boost.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"skills": [
1111
"fortify-development",
1212
"laravel-best-practices",
13+
"socialite-development",
1314
"wayfinder-development",
1415
"pest-testing",
1516
"inertia-react-development",

composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
"require": {
1212
"php": "^8.3",
1313
"inertiajs/inertia-laravel": "^3.0",
14+
"laravel/cashier-paddle": "^2.8",
1415
"laravel/fortify": "^1.34",
1516
"laravel/framework": "^13.7",
1617
"laravel/sanctum": "^4.0",
18+
"laravel/socialite": "^5.27",
1719
"laravel/tinker": "^3.0",
1820
"laravel/wayfinder": "^0.1.14"
1921
},

0 commit comments

Comments
 (0)