socialiteproviders/qq
QQ OAuth provider for Laravel Socialite, letting your app add Tencent QQ login with minimal setup. Install via Composer, configure your app ID and key, and authenticate QQ users through the familiar Socialite API.
What the package actually is. A thin, read-only subtree split of a single provider inside the SocialiteProviders/Providers monorepo. It contributes one driver class and one listener that teaches laravel/socialite how to speak Tencent QQ's OAuth 2.0 dialect. The entire functional surface is roughly 100–150 lines. This is not architecture; it is a protocol adapter.
Architecture fit. Fits cleanly if and only if the host application is Laravel and already uses Socialite for other identity providers. It registers through the SocialiteWasCalled event and slots into the existing Socialite::driver('qq') contract, which means it inherits Socialite's state/CSRF handling, redirect flow, and User abstraction for free. There is no new infrastructure, no persistence, no service to operate. If the app is Symfony, Slim, or a non-Laravel PHP stack, the package is unusable — Socialite is Laravel-coupled — and the correct move is league/oauth2-client with a hand-written QQ provider.
Integration feasibility. The code is trivial; the constraints are not. Three items dominate:
socialiteproviders/manager shim have both moved since (Laravel 10, 11, 12; PHP 8.3/8.4). The split repo's tags are generated from the upstream monorepo, so a three-year gap plausibly means the illuminate/support constraint is pinned to ^6|^7|^8|^9 and will not resolve on a modern Laravel app without --with-all-dependencies gymnastics or a fork. This must be verified by a spike, not by reading the README.graph.qq.com/oauth2.0/me, which returns a JSONP-wrapped payload (callback( {...} );) containing openid; profile data requires a second call to user/get_user_info with oauth_consumer_key and openid as query parameters. The provider absorbs all of this — which is precisely the value it delivers — but it also means any bug in that parsing is a bug you cannot patch in place (see Operational Impact).openid (app-scoped) and ideally unionid (developer-account-scoped, stable across apps).Technical risk.
| Risk | Severity | Notes |
|---|---|---|
| Composer constraint conflict on Laravel 10+ | High | Blocks adoption outright; cheap to test |
| Abandoned upstream / no security response | Medium | 49 stars, no release in 3 years, no issue tracker on the split repo |
| QQ互联 app approval | High | Business license + ICP-filed domain + Tencent review; days-to-weeks, outside engineering control |
unionid not enabled |
Medium | Without it, identity is per-app; migration later is painful |
| Error semantics | Medium | Graph API returns HTTP 200 with ret != 0; naive monitoring sees 100% success |
Avatar hotlinking (qlogo.cn) |
Low | May be blocked or rate-limited; mirror to your own storage |
| Latency from non-CN regions | Medium | Token exchange + profile fetch can add 400–1500 ms; timeout budget matters |
Key questions to answer before committing.
composer require socialiteproviders/qq resolve cleanly against our current Laravel and PHP versions? If not, is upstream main usable, or is a fork required?unionid? If we may ever run more than one app or tenant, yes — enable it at registration time.Stack fit. Accept only for Laravel 9+ applications already running Socialite. Reject for non-Laravel PHP; write the provider yourself in that case — it is a day of work.
Build vs. buy. Given the size of the artifact, treat buy as a convenience, not a commitment. The realistic decision tree:
composer-patches for this; a fork is cleaner and lets us widen constraints ourselves.Migration path. Greenfield: add the package, register the listener (note Laravel 11+ has no default EventServiceProvider — wire Event::listen(SocialiteWasCalled::class, …) in AppServiceProvider), add a qq block in config/services.php, add routes, ship behind a feature flag. Brownfield: no migration is required — it is additive and does not touch existing providers. The only shared surface is the users table, which should not be modified; introduce a separate social_identities table (provider, provider_user_id = openid, unionid, raw JSON, linked_at) so that adding or dropping a provider never touches core user rows.
Compatibility checklist. socialiteproviders/manager major version, illuminate/support constraint, laravel/socialite major version, PHP version, and whether the listener registration style matches (the v3 SocialiteWasCalled event vs. older registration). Confirm on a throwaway app, not in the main repo.
Sequencing.
composer require; drive a real login with a test QQ account (QQ互联 allows a small whitelist of test users). Measure latency from our deployment region.social_identities migration, controller, state handling (session-backed for web; ->stateless() only if an SPA/API flow genuinely requires it, and only with a separately validated CSRF strategy), error routes, feature flag with a kill switch.ret/msg, endpoint latency, and failure reason; alerting on failure-rate spikes.Maintenance. The package itself is near-zero maintenance when healthy — Socialite handles the moving parts. The ongoing cost is (a) tracking upstream for a release that widens framework constraints, and (b) monitoring QQ's endpoint behavior, which changes without notice and without a changelog. Because the repo is a read-only split, you cannot merge a fix into it: issues and PRs live in the monorepo, and a bug that matters to you may sit unfixed indefinitely with 49 stars of community pressure behind it. Plan for ownership: assign a named maintainer and decide up front whether that person can fork rather than wait.
Support. First-line support burden is modest but concentrated in one place: "QQ login didn't work" is almost never a code bug. It is a rejected redirect_uri (must match the registered domain exactly; wildcards are typically refused), a suspended or un-reviewed QQ app, a user who denied consent, or a network failure between your region and Tencent. Build a support runbook that maps symptoms to those causes, and surface the QQ ret code in your error page or logs so support can classify without engineering.
Scaling. The OAuth handshake is per-login and stateless on your side, so it scales with your web tier; there is no shared resource to saturate. The real capacity concerns are external: Graph API QPS limits, and the fact that each login costs two sequential round trips to Tencent. From servers outside mainland China, budget 400–1500 ms and set aggressive timeouts with a single retry for the token exchange only — never retry the profile fetch blindly if you have already established a session. Mirror avatars to your own storage rather than hotlinking qlogo.cn, both for latency and for longevity.
Failure modes to instrument.
ret != 0 with HTTP 200 — the single most likely thing to be missed by generic HTTP health checks.openid present but unionid absent because it was never enabled at registration.state mismatch or replay on session-backed flows; explicit handling for users who land on the callback with an expired session.code absent because the user denied consent — a normal path, not an error.Ramp-up. For an engineer who already knows Socialite, half a day to read the driver and a day to wire and test. For an engineer who does not, add a day for Socialite's event registration and User contract. The genuinely long pole is organizational, not technical: QQ互联 registration and review, business-entity documentation, and ICP filing can consume one to three weeks and are entirely outside the team's control. Staff accordingly, and treat the 0.635 score as a fair signal — the code is fine, but the package is stale, thinly adopted, and gated behind a market-entry process that no amount of engineering effort can shortcut.
How can I help you explore Laravel packages today?