Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Login Laravel Package

styleci/login

StyleCI Login adds StyleCI OAuth authentication to Laravel applications, letting users sign in with their StyleCI account. It provides a ready-made driver and routes so you can integrate secure single sign-on with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and confirm compatibility first. The package lives under the GrahamDeprecated org, which is where Graham Campbell moves repositories he no longer maintains. Before writing a line of integration code, run composer require styleci/login in a scratch branch and check what Laravel/Socialite versions the constraint resolves against. On a modern Laravel app (10/11/12) you will likely hit a constraint conflict; on a Laravel 5.6–6.x app it should install cleanly. Read composer.json in the package before committing to anything — the version constraints tell you more about the package's health than the README does.

2. Register a GitHub OAuth App. This is the real "first step" regardless of the package. In GitHub → Settings → Developer settings → OAuth Apps, create an app with:

  • Homepage URL: your app URL
  • Authorization callback URL: the exact callback route the package registers (inspect src/ routes or the published config — do not guess, and do not add a trailing slash)

Then set the credentials in .env:

GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GITHUB_REDIRECT_URI="${APP_URL}/login/github/callback"

3. Where to look first. The package is small — read it end to end before wiring it up. In order:

  • src/ — there will be a service provider, a controller (or two: redirect + callback), and probably a thin wrapper over laravel/socialite's GitHub driver. There is no hidden magic; it is almost certainly a convenience layer.
  • config/ — if a config file exists, php artisan vendor:publish --tag=... it and read every key. This is where the route prefix, guard, and scopes usually live.
  • routes/ or the service provider's boot() — this tells you exactly which URIs get registered and whether they are public or behind middleware.

4. First use case. The intended day-to-day use is "Sign in with GitHub" for a developer-facing app: internal dashboards, admin panels, CI-adjacent tooling, anything where the user base is already developers and a GitHub identity is a reasonable primary credential. Drop a link to the redirect route into your login Blade view, let the package handle the OAuth dance, and resolve the returned GitHub user to a local User record in your callback handling.

If you are not building a developer-facing tool, stop here and use laravel/socialite directly — the package's value is a saved afternoon, not a feature set.

Implementation Patterns

Pattern 1 — Thin package, thick app. Treat the package as "Socialite with routes." Let it own the OAuth handshake; own the user provisioning yourself. The callback typically hands you a Socialite User (or a package wrapper around one); do the mapping in your own listener/controller:

$github = Socialite::driver('github')->user();

$user = User::updateOrCreate(
    ['github_id' => $github->getId()],
    [
        'name'     => $github->getName() ?? $github->getNickname(),
        'email'    => $github->getEmail(),
        'avatar'   => $github->getAvatar(),
    ]
);

Auth::login($user, remember: true);

Matching on github_id (not email) is the durable key. Emails change; GitHub numeric IDs do not.

Pattern 2 — Bind to an existing account by email, then attach. For apps that already have password users, look up by email on first GitHub login and set github_id on the existing row rather than creating a duplicate. Require user:email scope and verify email_verified before trusting the address — otherwise this is an account-takeover vector.

Pattern 3 — Gate access, don't just authenticate. The highest-value use of GitHub identity is authorisation: "is this person in the org / on the team / a collaborator on repo X." After login, hit the GitHub API with the stored token and check membership, then cache the result. This is the pattern StyleCI itself uses — GitHub login is the access control plane.

// Pseudocode: cache aggressively, this is a remote call on every request otherwise
$allowed = Cache::remember("gh:org:{$user->github_id}", now()->addMinutes(15), fn () =>
    $user->githubTokenCan('read:org') && $this->isOrgMember($user->github_token)
);
abort_unless($allowed, 403);

Pattern 4 — Store the token, encrypted. Persist the OAuth token in an encrypted cast column if you plan to call the API on the user's behalf. Add a github_token and github_scopes column; check scopes before calling endpoints rather than discovering a 403 in production.

Pattern 5 — Testing. Do not let tests hit GitHub. Either mock Socialite::shouldReceive('driver->user'), or, on Socialite 5+, use the fake:

Socialite::fake('github', (new User)->map([
    'id' => 12345, 'nickname' => 'graham', 'email' => '[email protected]',
]));

Assert 302 to GitHub on the redirect route, assert the session/guard state after the callback, and keep one manual smoke test against a real OAuth app because the fake will not catch callback-URL mismatches.

Pattern 6 — Override, don't fork. If you need different post-login behaviour, bind your own implementation of the package's controller or listener in a service provider rather than editing vendor/. Extend the package class and re-register the route, or skip the package's routes entirely (config flag or by not loading them) and point GitHub at your own callback URL that calls the package's service.

Gotchas and Tips

  • Zero stars, zero dependents, deprecation-org address. This is a read-only artifact, not a maintained dependency. Pin the exact version, commit composer.lock, and set a calendar reminder to re-evaluate. Assume no security patches, no Laravel 12 support, and no response to issues. For a login path — your most security-sensitive surface — that is a real cost. Budget half a day to reimplement on plain Socialite; it is a small amount of code and you will own it.
  • Callback URL must match byte-for-byte. http vs https, www vs apex, trailing slash, port, and APP_URL inconsistency between environments are the top three causes of redirect_uri_mismatch. Set GITHUB_REDIRECT_URI explicitly per environment instead of relying on route generation.
  • state and session loss. OAuth state is stored in the session. Users who block cookies, hit the callback in a different tab after session expiry, or land behind a load balancer without sticky sessions will get "invalid state." Make the failure message actionable rather than a 500.
  • GitHub may return a null email. Users with private emails (the default for many) yield null unless you request user:email and call the emails endpoint. Decide up front: require email, or allow email-less accounts keyed on github_id.
  • Scope creep is silent. Adding a scope means every existing user must re-authorise before the new scope is present. Store granted scopes and check them; do not assume read:org exists because you put it in config.
  • Rate limits. Unauthenticated GitHub API is 60 req/hr; authenticated 5,000/hr per user. A per-request org-membership check will burn through this under any load — cache for 10–15 minutes and handle 403 with X-RateLimit-Remaining: 0 as a soft failure, not a hard logout.
  • Token revocation. GitHub tokens can be revoked from the user's settings at any time. Treat a 401 from the API as "re-authenticate," clear the stored token, and redirect to the login route rather than leaving the user in a broken half-logged-in state.
  • Config caching. php artisan config:cache in deploy is the classic trap: if the package reads env() outside a config file, it silently returns null in production. Publish the config and verify with php artisan config:show after deploying.
  • Don't log the token. OAuth tokens show up in dd(), exception traces, and Telescope payloads. Add the token column to your model's $hidden and scrub it in any request logger.
  • Extension point to prefer: the service provider's container bindings. If the package binds a Login/Provider contract, rebind it in AppServiceProvider — that is the cheapest way to customise without forking. If there is no contract, that absence is itself the argument for using Socialite directly.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource