{"id":18550273,"url":"https://github.com/xp-forge/web-auth","last_synced_at":"2026-04-25T22:01:12.715Z","repository":{"id":41867028,"uuid":"202692728","full_name":"xp-forge/web-auth","owner":"xp-forge","description":"Web Authentication","archived":false,"fork":false,"pushed_at":"2026-01-04T20:13:55.000Z","size":293,"stargazers_count":0,"open_issues_count":6,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-05T10:34:10.386Z","etag":null,"topics":["authentication","basic-authentication","cas","jwt","oauth","oauth1","oauth2","oauth2-credentials","php","pkce-oauth","userinfo","xp-framework"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xp-forge.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-08-16T08:47:32.000Z","updated_at":"2026-01-04T20:13:33.000Z","dependencies_parsed_at":"2024-02-25T14:33:56.679Z","dependency_job_id":"8cbba886-d96a-4e38-9097-1af76607ac25","html_url":"https://github.com/xp-forge/web-auth","commit_stats":null,"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/xp-forge/web-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fweb-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fweb-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fweb-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fweb-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xp-forge","download_url":"https://codeload.github.com/xp-forge/web-auth/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xp-forge%2Fweb-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32278249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","basic-authentication","cas","jwt","oauth","oauth1","oauth2","oauth2-credentials","php","pkce-oauth","userinfo","xp-framework"],"created_at":"2024-11-06T21:04:03.590Z","updated_at":"2026-04-25T22:01:12.704Z","avatar_url":"https://github.com/xp-forge.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Web Authentication\n==================\n\n[![Build status on GitHub](https://github.com/xp-forge/web-auth/workflows/Tests/badge.svg)](https://github.com/xp-forge/web-auth/actions)\n[![XP Framework Module](https://raw.githubusercontent.com/xp-framework/web/master/static/xp-framework-badge.png)](https://github.com/xp-framework/core)\n[![BSD Licence](https://raw.githubusercontent.com/xp-framework/web/master/static/licence-bsd.png)](https://github.com/xp-framework/core/blob/master/LICENCE.md)\n[![Requires PHP 7.4+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-7_4plus.svg)](http://php.net/)\n[![Supports PHP 8.0+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-8_0plus.svg)](http://php.net/)\n[![Latest Stable Version](https://poser.pugx.org/xp-forge/web-auth/version.svg)](https://packagist.org/packages/xp-forge/web-auth)\n\nAuthentication for web services. Supports authenticating URLs with fragments such as `https://example.com/#/users/thekid` without losing information when redirecting.\n\n☑ Verified with Twitter (OAuth 1), Microsoft Office 365, Facebook, GitHub and Google (OAuth 2).\n\nExamples\n--------\n### HTTP basic authentication:\n\n```php\nuse web\\auth\\Basic;\nuse util\\Secret;\n\n$auth= new Basic('Administration', function($user, Secret $secret) {\n  return 'admin' === $user \u0026\u0026 $secret-\u003eequals('secret') ? ['id' =\u003e 'admin'] : null;\n});\n\nreturn ['/' =\u003e $auth-\u003erequired(function($req, $res) {\n  $res-\u003esend('Hello @'.$req-\u003evalue('user')['id'], 'text/plain');\n})];\n```\n\n### Authentication via Twitter:\n\n```php\nuse web\\auth\\SessionBased;\nuse web\\auth\\oauth\\OAuth1Flow;\nuse web\\session\\ForTesting;\n\n$flow= new OAuth1Flow(\n  'https://api.twitter.com/oauth',\n  [$credentials-\u003enamed('twitter_oauth_key'), $credentials-\u003enamed('twitter_oauth_secret')],\n  $callback\n);\n$auth= new SessionBased(\n  $flow,\n  new ForTesting(),\n  $flow-\u003efetchUser('https://api.twitter.com/1.1/account/verify_credentials.json')\n);\n\nreturn ['/' =\u003e $auth-\u003erequired(function($req, $res) {\n  $res-\u003esend('Hello @'.$req-\u003evalue('user')['screen_name'], 'text/plain');\n})];\n```\n\n*The $callback parameter should be the path matching the path in the callback URI registered with Twitter.*\n\n### Authentication via GitHub:\n\n```php\nuse web\\auth\\SessionBased;\nuse web\\auth\\oauth\\OAuth2Flow;\nuse web\\session\\ForTesting;\n\n$flow= new OAuth2Flow(\n  'https://github.com/login/oauth/authorize',\n  'https://github.com/login/oauth/access_token',\n  [$credentials-\u003enamed('github_oauth_key'), $credentials-\u003enamed('github_oauth_secret')],\n  $callback\n);\n$auth= new SessionBased(\n  $flow,\n  new ForTesting(),\n  $flow-\u003efetchUser('https://api.github.com/user')\n);\n\nreturn ['/' =\u003e $auth-\u003erequired(function($req, $res) {\n  $res-\u003esend('Hello @'.$req-\u003evalue('user')['login'], 'text/plain');\n})];\n```\n\n*The $callback parameter should be the path matching the path in the callback URI registered with GitHub.*\n\n### Authentication via Google:\n\n```php\nuse web\\auth\\SessionBased;\nuse web\\auth\\oauth\\OAuth2Flow;\nuse web\\session\\ForTesting;\n\n$flow= new OAuth2Flow(\n  'https://accounts.google.com/o/oauth2/v2/auth',\n  'https://oauth2.googleapis.com/token',\n  [$credentials-\u003enamed('google_oauth_key'), $credentials-\u003enamed('google_oauth_secret')],\n  $callback,\n  ['https://www.googleapis.com/auth/userinfo.profile']\n);\n$auth= new SessionBased(\n  $flow,\n  new ForTesting(),\n  $flow-\u003efetchUser('https://openidconnect.googleapis.com/v1/userinfo')\n);\n\nreturn ['/' =\u003e $auth-\u003erequired(function($req, $res) {\n  $res-\u003esend('Hello @'.$req-\u003evalue('user')['name'], 'text/plain');\n})];\n```\n\n*The $callback parameter should be the path matching the path in the callback URI registered with GitHub.*\n\n### Authentication via Office 365 Azure AD:\n\n```php\nuse util\\Secret;\nuse web\\auth\\SessionBased;\nuse web\\auth\\oauth\\{OAuth2Flow, BySecret, ByCertificate, ByPKCE};\nuse web\\session\\ForTesting;\n\n// Depending on what you have set up under \"Certificates \u0026 Secrets\", use one\n// of the following. For certificate-based authentication, $privateKey can\n// hold either the key's contents or reference it as 'file://private.key'\n$credentials= new BySecret('[APP-ID]', new Secret('...'));\n$credentials= new ByCertificate('[APP-ID]', '[THUMBPRINT]', $privateKey);\n$credentials= new ByPKCE('[APP-ID]', 'S256');\n\n$flow= new OAuth2Flow(\n  'https://login.microsoftonline.com/[TENANT_ID]/oauth2/v2.0/authorize',\n  'https://login.microsoftonline.com/[TENANT_ID]/oauth2/v2.0/token',\n  $credentials,\n  $callback,\n  ['openid', 'profile', 'offline_access', 'User.Read']\n);\n$auth= new SessionBased(\n  $flow,\n  new ForTesting(),\n  $flow-\u003efetchUser('https://graph.microsoft.com/v1.0/me')\n);\n\nreturn ['/' =\u003e $auth-\u003erequired(function($req, $res) {\n  $res-\u003esend('Hello @'.$req-\u003evalue('user')['login'], 'text/plain');\n})];\n```\n\n*The $callback parameter should be the path matching the path in the callback URI registered with the Azure AD application.*\n\n### Authentication via [CAS](https://apereo.github.io/cas) (\"Central Authentication Service\"):\n\n```php\nuse web\\auth\\SessionBased;\nuse web\\auth\\cas\\CasFlow;\nuse web\\session\\ForTesting;\n\n$flow= new CasFlow('https://sso.example.com/');\n$auth= new SessionBased($flow, new ForTesting());\n\nreturn ['/' =\u003e $auth-\u003erequired(function($req, $res) {\n  $res-\u003esend('Hello @'.$req-\u003evalue('user')['username'], 'text/plain');\n})];\n```\n\nTarget URLs\n-----------\nBy default, the flow instances use the request URI to determine where the service is running. Behind a proxy, this is most probably not the user-facing URI. To change this behavior, use the `target()` method and pass a `UseURL` instance as follows:\n\n```php\nuse web\\auth\\UseURL;\nuse web\\auth\\cas\\CasFlow;\n\n$flow= (new CasFlow('https://sso.example.com/'))-\u003etarget(new UseURL('https://service.example.com/'));\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxp-forge%2Fweb-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxp-forge%2Fweb-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxp-forge%2Fweb-auth/lists"}