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

Oauth2 Server Php Laravel Package

bshaffer/oauth2-server-php

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require bshaffer/oauth2-server-php
    

    Add to composer.json:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "League\\OAuth2\\Server\\": "vendor/league/oauth2-server/"
        }
    }
    

    Run composer dump-autoload.

  2. Basic Server Initialization In a Laravel route (e.g., routes/api.php):

    use League\OAuth2\Server\ResourceServer;
    use League\OAuth2\Server\AuthorizationServer;
    
    $server = new ResourceServer(
        new \League\OAuth2\Server\Repository\DefaultAccessTokenRepository(),
        new \League\OAuth2\Server\Repository\DefaultClientRepository(),
        new \League\OAuth2\Server\Repository\DefaultScopeRepository(),
        new \League\OAuth2\Server\Repository\DefaultUserRepository(),
        'HS256', // Algorithm
        'your-secret-key' // Private key or shared secret
    );
    
  3. First Use Case: Protecting an API Endpoint

    Route::get('/protected', function () use ($server) {
        try {
            $request = \League\OAuth2\Server\RequestTypes\BearerTokenRequest::createFromGlobals();
            $server->validateAuthenticatedRequest($request);
            return response()->json(['message' => 'Access granted!']);
        } catch (\League\OAuth2\Server\Exception\OAuthServerException $e) {
            return response()->json(['error' => (string)$e], $e->getHttpStatusCode());
        }
    });
    

Where to Look First

  • League/OAuth2 Server Docs (Official documentation)
  • src/League/OAuth2/Server/ (Core classes)
  • tests/ (Example implementations and edge cases)

Implementation Patterns

1. Authorization Server Workflow

Issuing Tokens

$server = new AuthorizationServer(
    new \League\OAuth2\Server\Repository\DefaultClientRepository(),
    new \League\OAuth2\Server\Repository\DefaultAccessTokenRepository(),
    new \League\OAuth2\Server\Repository\DefaultRefreshTokenRepository(),
    new \League\OAuth2\Server\Repository\DefaultScopeRepository(),
    'HS256',
    'your-secret-key'
);

Route::post('/oauth/token', function () use ($server) {
    $request = \League\OAuth2\Server\RequestTypes\TokenRequest::createFromGlobals();
    $response = new \League\OAuth2\Server\ResponseTypes\BearerTokenResponse();
    return $server->respondToAccessTokenRequest($request, $response);
});

Grant Types

  • Password Grant (Client credentials + user credentials):

    $grant = new \League\OAuth2\Server\Grant\PasswordGrant(
        new \League\OAuth2\Server\Repository\DefaultUserRepository(),
        new \League\OAuth2\Server\Repository\DefaultClientRepository(),
        new \League\OAuth2\Server\Repository\DefaultAccessTokenRepository(),
        new \League\OAuth2\Server\Repository\DefaultRefreshTokenRepository()
    );
    $server->enableGrantType($grant, new \League\OAuth2\Server\RequestTypes\PasswordRequest());
    
  • Refresh Token Grant:

    $grant = new \League\OAuth2\Server\Grant\RefreshTokenGrant(
        new \League\OAuth2\Server\Repository\DefaultRefreshTokenRepository(),
        new \League\OAuth2\Server\Repository\DefaultAccessTokenRepository()
    );
    $server->enableGrantType($grant, new \League\OAuth2\Server\RequestTypes\RefreshTokenRequest());
    

2. Resource Server Workflow

Validating Requests

Route::get('/api/data', function () use ($server) {
    $request = \League\OAuth2\Server\RequestTypes\BearerTokenRequest::createFromGlobals();
    $server->validateAuthenticatedRequest($request);

    // Get the authenticated user (if using a custom user repo)
    $user = $server->getResourceOwnerRepository()->getResourceOwner($request->getServer()->get('PHP_AUTH_USER'));

    return response()->json(['data' => $user->toArray()]);
});

Custom Claims in Tokens

Override DefaultAccessTokenRepository to add custom claims:

class CustomAccessTokenRepository extends \League\OAuth2\Server\Repository\DefaultAccessTokenRepository {
    public function getNewToken($accessTokenId, $clientId, $userIdentifier, $scope, $accessToken, $expiresAt, $refreshToken = null, array $customClaims = []) {
        $customClaims['custom_field'] = 'value';
        return parent::getNewToken($accessTokenId, $clientId, $userIdentifier, $scope, $accessToken, $expiresAt, $refreshToken, $customClaims);
    }
}

3. Laravel Integration Tips

Middleware for Protected Routes

use League\OAuth2\Server\ResourceServer;

class Authenticate extends Middleware {
    protected $server;

    public function __construct(ResourceServer $server) {
        $this->server = $server;
    }

    public function handle($request, Closure $next) {
        $request = \League\OAuth2\Server\RequestTypes\BearerTokenRequest::createFromGlobals();
        $this->server->validateAuthenticatedRequest($request);
        return $next($request);
    }
}

Register in app/Http/Kernel.php:

protected $routeMiddleware = [
    'auth.oauth' => \App\Http\Middleware\Authenticate::class,
];

Using Laravel’s Auth System

Extend DefaultUserRepository to integrate with Laravel’s Auth:

class LaravelUserRepository extends \League\OAuth2\Server\Repository\DefaultUserRepository {
    public function getResourceOwner($username) {
        $user = \App\Models\User::where('username', $username)->first();
        return $user ? new \League\OAuth2\Server\Entity\UserEntity($user->id, $username) : null;
    }
}

Gotchas and Tips

Common Pitfalls

  1. Token Validation Failures

    • Issue: invalid_token or insufficient_scope errors.
    • Debugging:
      • Ensure the client_id and client_secret are correct.
      • Verify the token hasn’t expired (check exp claim).
      • Confirm scopes match (scope claim in token vs. requested scope).
    • Fix:
      try {
          $server->validateAuthenticatedRequest($request);
      } catch (\League\OAuth2\Server\Exception\OAuthServerException $e) {
          return response()->json(['error' => $e->getMessage()], $e->getHttpStatusCode());
      }
      
  2. Repository Mismatches

    • Issue: RepositoryNotFoundException or EntityNotFoundException.
    • Debugging:
      • Ensure all repositories (Client, AccessToken, User, etc.) are properly implemented.
      • Check if getClient() or getAccessToken() returns null for valid inputs.
    • Fix:
      // Example: Custom Client Repository
      class CustomClientRepository extends \League\OAuth2\Server\Repository\DefaultClientRepository {
          public function getClientEntity($clientIdentifier) {
              $client = \App\Models\Client::where('id', $clientIdentifier)->first();
              return $client ? new \League\OAuth2\Server\Entity\ClientEntity(
                  $client->id,
                  $client->secret,
                  $client->redirectUri
              ) : null;
          }
      }
      
  3. Cryptographic Issues

    • Issue: invalid_signature or invalid_token with JWT.
    • Debugging:
      • Verify the signing algorithm (HS256, RS256, etc.) matches in both server and client.
      • Ensure the secret or private key is correct and accessible.
    • Fix:
      // For RS256 (asymmetric), use:
      $server = new ResourceServer(
          // ...,
          'RS256',
          file_get_contents('path/to/private.key')
      );
      
  4. State Management in Authorization Code Flow

    • Issue: CSRF attacks or missing state parameter.
    • Fix:
      • Always include a state parameter in authorization requests.
      • Validate it on the redirect back to your app.
      $state = bin2hex(random_bytes(32));
      session(['oauth_state' => $state]);
      return redirect()->to("https://oauth-provider.com/authorize?response_type=code&client_id={$clientId}&redirect_uri={$redirectUri}&state={$state}");
      

Performance Tips

  1. Caching Tokens
    • Use Laravel’s
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.
labyrinthe/connect-php
encore2/laravel-admin2
cboxdk/laravel-console-kit
shapecode/doctrine-dbal-datetimeutc
gilads-otiannoh254/inertia-protocol
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite
faghy/laracashbook
roundly-consulting/google-places-for-laravel
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
adachsoft/cli-process-tester
adachsoft/changelog-linter
adachsoft/collection
adachsoft/php-code-style
adachsoft/api-version-bundle