{"record":{"id":"85cbb2c2b7dc3e89","repo":"thephpleague/oauth2-server","slug":"access-denied-the-user-the-request","errorCode":"access_denied","errorMessage":"The user denied the request","messagePattern":"The user denied the request","errorType":"http","errorClass":"OAuthServerException","httpStatus":401,"severity":"info","filePath":"src/Grant/ImplicitGrant.php","lineNumber":195,"sourceCode":"            $response = new RedirectResponse();\n            $response->setRedirectUri(\n                $this->makeRedirectUri(\n                    $finalRedirectUri,\n                    [\n                        'access_token' => $accessToken->toString(),\n                        'token_type'   => 'Bearer',\n                        'expires_in'   => $accessToken->getExpiryDateTime()->getTimestamp() - time(),\n                        'state'        => $authorizationRequest->getState(),\n                    ],\n                    $this->queryDelimiter\n                )\n            );\n\n            return $response;\n        }\n\n        // The user denied the client, redirect them back with an error\n        throw OAuthServerException::accessDenied(\n            'The user denied the request',\n            $this->makeRedirectUri(\n                $finalRedirectUri,\n                [\n                    'state' => $authorizationRequest->getState(),\n                ],\n                $this->queryDelimiter\n            )\n        );\n    }\n}\n","sourceCodeStart":177,"sourceCodeEnd":207,"githubUrl":"https://github.com/thephpleague/oauth2-server/blob/9d2f6fc0a0b5aa1bb02506971d3a4ecff2c6526c/src/Grant/ImplicitGrant.php#L177-L207","documentation":"OAuthServerException::accessDenied('The user denied the request') is thrown by ImplicitGrant::completeAuthorizationRequest when the authorization request's user did not approve the client. The library redirects the user agent back to the client's redirect URI with error=access_denied and the original state, per RFC 6749 section 4.2.2.1. It is an expected, user-driven outcome, not a bug.","triggerScenarios":"completeAuthorizationRequest where AuthorizationRequest::getAuthorizationApproved? is false (approveAuthorizationRequest never called) or authorizationApproved was set to false by the user-approval UI; the grant then builds the error redirect and throws.","commonSituations":"User clicks 'Deny' on the consent screen; authorization server app never calls $authorizationRequest->approveAuthorizationRequest() due to routing/session bugs; consent screen times out or user cancels; developer forgets to set approval state in the user-approval endpoint.","solutions":["Treat this as normal control flow: catch OAuthServerException, inspect the redirect response, and show 'authorization denied' to the user","If denial is unexpected, verify your consent screen calls approveAuthorizationRequest(true) when the user approves","Re-initiate the authorization flow when the user wants to try again","Include state handling on the client so the error redirect can be matched to the original request"],"exampleFix":"// before\n$grant->completeAuthorizationRequest($authRequest, $response); // approval state unset\n// after\nif ($userApproved) {\n    $authRequest->approveAuthorizationRequest(true);\n}\ntry {\n    return $grant->completeAuthorizationRequest($authRequest, $response);\n} catch (OAuthServerException $e) {\n    // user denied: redirect already carries error=access_denied&state=...\n}","handlingStrategy":"try-catch","validationCode":"if (!$authorizationRequest->isAuthorizationApproved()) {\n    // user has not approved yet; render consent screen instead of completing\n}","typeGuard":"function isApproved(AuthorizationRequest $r): bool {\n    return $r->isAuthorizationApproved() === true;\n}","tryCatchPattern":"try {\n    return $grant->completeAuthorizationRequest($authRequest, $response);\n} catch (OAuthServerException $e) {\n    if ($e->getErrorType() === 'access_denied') {\n        // expected user denial: redirect carries error=access_denied&state=...\n        return $e->generateHttpResponse($response);\n    }\n    throw $e;\n}","preventionTips":["Always call approveAuthorizationRequest(true) when the user consents","Handle the state parameter on the client to correlate denial redirects","Design UX so denial is a normal outcome, not an application error"],"tags":["oauth2","implicit-grant","access-denied","user-consent"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"9d2f6fc0a0b5aa1bb02506971d3a4ecff2c6526c","analyzedAt":"2026-09-15T22:33:30.452Z","contentChangedAt":"2026-09-15T22:33:30.452Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}