src/Grant/AuthCodeGrant.php
public function respondToAccessTokenRequest(
        ServerRequestInterface $request,
        ResponseTypeInterface $responseType,
        DateInterval $accessTokenTTL
    ) {
        // Validate request
        $client = $this->validateClient($request);
        $encryptedAuthCode = $this->getRequestParameter('code', $request, null);

        if ($encryptedAuthCode === null) {
            throw OAuthServerException::invalidRequest('code');
        }

        try {
            $authCodePayload = json_decode($this->decrypt($encryptedAuthCode));

            $this->validateAuthorizationCode($authCodePayload, $client, $request);

            $scopes = $this->scopeRepository->finalizeScopes(
                $this->validateScopes($authCodePayload->scopes),
                $this->getIdentifier(),
                $client,
                $authCodePayload->user_id
            );
        } catch (LogicException $e) {
            throw OAuthServerException::invalidRequest('code', 'Cannot decrypt the authorization code', $e);
        }

        // Validate code challenge
        if ($this->enableCodeExchangeProof === true) {
            $codeVerifier = $this->getRequestParameter('code_verifier', $request, null);

            if ($codeVerifier === null) {
                throw OAuthServerException::invalidRequest('code_verifier');
            }

            // Validate code_verifier according to RFC-7636
            // @see: https://tools.ietf.org/html/rfc7636#section-4.1
            if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $codeVerifier) !== 1) {
                throw OAuthServerException::invalidRequest(
                    'code_verifier',
                    'Code Verifier must follow the specifications of RFC-7636.'
                );
            }

            switch ($authCodePayload->code_challenge_method) {
                case 'plain':
                    if (hash_equals($codeVerifier, $authCodePayload->code_challenge) === false) {
                        throw OAuthServerException::invalidGrant('Failed to verify `code_verifier`.');
                    }

                    break;
                case 'S256':
                    if (
                        hash_equals(
                            strtr(rtrim(base64_encode(hash('sha256', $codeVerifier, true)), '='), '+/', '-_'),
                            $authCodePayload->code_challenge
                        ) === false
                    ) {
                        throw OAuthServerException::invalidGrant('Failed to verify `code_verifier`.');
                    }
                    // @codeCoverageIgnoreStart
                    break;
                default:
                    throw OAuthServerException::serverError(
                        sprintf(
                            'Unsupported code challenge method `%s`',
                            $authCodePayload->code_challenge_method
                        )
                    );
                // @codeCoverageIgnoreEnd
            }
        }

        // Issue and persist new access token
        $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $authCodePayload->user_id, $scopes);
        $this->getEmitter()->emit(new RequestEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request));
        $responseType->setAccessToken($accessToken);

        // Issue and persist new refresh token if given
        $refreshToken = $this->issueRefreshToken($accessToken);

        if ($refreshToken !== null) {
            $this->getEmitter()->emit(new RequestEvent(RequestEvent::REFRESH_TOKEN_ISSUED, $request));
            $responseType->setRefreshToken($refreshToken);
        }

        // Revoke used auth code
        $this->authCodeRepository->revokeAuthCode($authCodePayload->auth_code_id);

        return $responseType;
    }
public function respondToAccessTokenRequest(
        ServerRequestInterface $request,
        ResponseTypeInterface $responseType,
        DateInterval $accessTokenTTL
    ) {
        // Validate request
        $client = $this->validateClient($request);
        $encryptedAuthCode = $this->getRequestParameter('code', $request, null);

        if ($encryptedAuthCode === null) {
            throw OAuthServerException::invalidRequest('code');
        }

        try {
            $authCodePayload = json_decode($this->decrypt($encryptedAuthCode));

            $this->validateAuthorizationCode($authCodePayload, $client, $request);

            $scopes = $this->scopeRepository->finalizeScopes(
                $this->validateScopes($authCodePayload->scopes),
                $this->getIdentifier(),
                $client,
                $authCodePayload->user_id
            );
        } catch (LogicException $e) {
            throw OAuthServerException::invalidRequest('code', 'Cannot decrypt the authorization code', $e);
        }

        // Validate code challenge
        if ($this->enableCodeExchangeProof === true) {
            $codeVerifier = $this->getRequestParameter('code_verifier', $request, null);

            if ($codeVerifier === null) {
                throw OAuthServerException::invalidRequest('code_verifier');
            }

            // Validate code_verifier according to RFC-7636
            // @see: https://tools.ietf.org/html/rfc7636#section-4.1
            if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $codeVerifier) !== 1) {
                throw OAuthServerException::invalidRequest(
                    'code_verifier',
                    'Code Verifier must follow the specifications of RFC-7636.'
                );
            }

            switch ($authCodePayload->code_challenge_method) {
                case 'plain':
                    if (hash_equals($codeVerifier, $authCodePayload->code_challenge) === false) {
                        throw OAuthServerException::invalidGrant('Failed to verify `code_verifier`.');
                    }

                    break;
                case 'S256':
                    if (
                        hash_equals(
                            strtr(rtrim(base64_encode(hash('sha256', $codeVerifier, true)), '='), '+/', '-_'),
                            $authCodePayload->code_challenge
                        ) === false
                    ) {
                        throw OAuthServerException::invalidGrant('Failed to verify `code_verifier`.');
                    }
                    // @codeCoverageIgnoreStart
                    break;
                default:
                    throw OAuthServerException::serverError(
                        sprintf(
                            'Unsupported code challenge method `%s`',
                            $authCodePayload->code_challenge_method
                        )
                    );
                // @codeCoverageIgnoreEnd
            }
        }

        // Issue and persist new access token
        $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $authCodePayload->user_id, $scopes);
        $this->getEmitter()->emit(new RequestEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request));
        $responseType->setAccessToken($accessToken);

        // Issue and persist new refresh token if given
        $refreshToken = $this->issueRefreshToken($accessToken);

        if ($refreshToken !== null) {
            $this->getEmitter()->emit(new RequestEvent(RequestEvent::REFRESH_TOKEN_ISSUED, $request));
            $responseType->setRefreshToken($refreshToken);
        }

        // Revoke used auth code
        $this->authCodeRepository->revokeAuthCode($authCodePayload->auth_code_id);

        return $responseType;
    }
public function respondToAccessTokenRequest ( ServerRequestInterface $ request , ResponseTypeInterface $ responseType , DateInterval $ accessTokenTTL ) { // Validate request $ client = $ this -> validateClient ( $ request ) ; $ encryptedAuthCode = $ this -> getRequestParameter ( 'code' , $ request , null ) ; if ( $ encryptedAuthCode === null ) { throw OAuthServerException :: invalidRequest ( 'code' ) ; } try { $ authCodePayload = json_decode ( $ this -> decrypt ( $ encryptedAuthCode ) ) ; $ this -> validateAuthorizationCode ( $ authCodePayload , $ client , $ request ) ; $ scopes = $ this -> scopeRepository -> finalizeScopes ( $ this -> validateScopes ( $ authCodePayload -> scopes ) , $ this -> getIdentifier ( ) , $ client , $ authCodePayload -> user_id ) ; } catch ( LogicException $ e ) { throw OAuthServerException :: invalidRequest ( 'code' , 'Cannot decrypt the authorization code' , $ e ) ; } // Validate code challenge if ( $ this -> enableCodeExchangeProof === true ) { $ codeVerifier = $ this -> getRequestParameter ( 'code_verifier' , $ request , null ) ; if ( $ codeVerifier === null ) { throw OAuthServerException :: invalidRequest ( 'code_verifier' ) ; } // Validate code_verifier according to RFC-7636 // @see: https://tools.ietf.org/html/rfc7636#section-4.1 if ( preg_match ( '/^[A-Za-z0-9-._~]{43,128}$/' , $ codeVerifier ) !== 1 ) { throw OAuthServerException :: invalidRequest ( 'code_verifier' , 'Code Verifier must follow the specifications of RFC-7636.' ) ; } switch ( $ authCodePayload -> code_challenge_method ) { case 'plain' : if ( hash_equals ( $ codeVerifier , $ authCodePayload -> code_challenge ) === false ) { throw OAuthServerException :: invalidGrant ( 'Failed to verify `code_verifier`.' ) ; } break ; case 'S256' : if ( hash_equals ( strtr ( rtrim ( base64_encode ( hash ( 'sha256' , $ codeVerifier , true ) ) , '=' ) , '+/' , '-_' ) , $ authCodePayload -> code_challenge ) === false ) { throw OAuthServerException :: invalidGrant ( 'Failed to verify `code_verifier`.' ) ; } // @codeCoverageIgnoreStart break ; default : throw OAuthServerException :: serverError ( sprintf ( 'Unsupported code challenge method `%s`' , $ authCodePayload -> code_challenge_method ) ) ; // @codeCoverageIgnoreEnd } } // Issue and persist new access token $ accessToken = $ this -> issueAccessToken ( $ accessTokenTTL , $ client , $ authCodePayload -> user_id , $ scopes ) ; $ this -> getEmitter ( ) -> emit ( new RequestEvent ( RequestEvent :: ACCESS_TOKEN_ISSUED , $ request ) ) ; $ responseType -> setAccessToken ( $ accessToken ) ; // Issue and persist new refresh token if given $ refreshToken = $ this -> issueRefreshToken ( $ accessToken ) ; if ( $ refreshToken !== null ) { $ this -> getEmitter ( ) -> emit ( new RequestEvent ( RequestEvent :: REFRESH_TOKEN_ISSUED , $ request ) ) ; $ responseType -> setRefreshToken ( $ refreshToken ) ; } // Revoke used auth code $ this -> authCodeRepository -> revokeAuthCode ( $ authCodePayload -> auth_code_id ) ; return $ responseType ; }
Respond to an access token request.

@param ServerRequestInterface $request
@param ResponseTypeInterface  $responseType
@param DateInterval           $accessTokenTTL

@throws OAuthServerException

@return ResponseTypeInterface
Respond to an access token request .