'; 73 | print_r($response->getBody()->__toString()); 74 | exit; 75 | } 76 | 77 | // Update the PSR-7 ResponseInterface object before the SDK uses it. 78 | $event->set($response); 79 | } 80 | 81 | public function setup(): self 82 | { 83 | // Register our PSR-14 ListenerProvider. 84 | $this->app->getConfiguration()->setEventListenerProvider($this->listener); 85 | 86 | // Register the events we want to listen for. 87 | $this->listener->on(HttpRequestBuilt::class, function (object $event): void { 88 | $this->onHttpRequestBuilt($event); 89 | }); 90 | $this->listener->on(HttpResponseReceived::class, function (object $event): void { 91 | $this->onHttpResponseReceived($event); 92 | }); 93 | 94 | return $this; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/Example/Management.php: -------------------------------------------------------------------------------- 1 | app = &$app; 27 | } 28 | 29 | /** 30 | * Query the users endpoint and retrieve details about a user. 31 | * 32 | * @param ManagementAPI $api An instance of the ManagementAPI to issue the request through. 33 | * @param string $sub The user identifier to query. 34 | * 35 | * @return null|array36 | */ 37 | public function getProfile( 38 | ManagementAPI $api, 39 | string $sub, 40 | ): ?array { 41 | $response = $api->users()->get($sub); 42 | 43 | if (! HttpResponse::wasSuccessful($response)) { 44 | exit('Management API request failed. Unable to get user.'); 45 | } 46 | 47 | return HttpResponse::decodeContent($response); 48 | } 49 | 50 | public function onIndexRoute( 51 | ApplicationRouter $router, 52 | ?stdClass $session, 53 | ): ?bool { 54 | if ($session instanceof stdClass) { 55 | $api = $this->app->getSdk()->management(); 56 | 57 | if ('POST' === $router->getMethod()) { 58 | $this->updateProfile($api, $session->user['sub']); 59 | } 60 | 61 | $profile = $this->getProfile($api, $session->user['sub']); 62 | 63 | $this->app->getTemplate()->render('management', [ 64 | 'session' => $session, 65 | 'router' => $router, 66 | 'cookies' => $_COOKIE, 67 | 'managementUserProfile' => $profile, 68 | ]); 69 | 70 | return true; 71 | } 72 | 73 | return null; 74 | } 75 | 76 | /** 77 | * Update the user_metadata of a user, as a demonstration of the process. 78 | * 79 | * @param ManagementAPI $api An instance of the ManagementAPI to issue the request through. 80 | * @param string $sub The user identifier to update metadata for. 81 | * 82 | * @return null|array 83 | */ 84 | public function updateProfile( 85 | ManagementAPI $api, 86 | string $sub, 87 | ): ?array { 88 | $response = $api->users()->update($sub, [ 89 | 'user_metadata' => [ 90 | 'quickstart_example' => 'Updated ' . date(DATE_RFC2822, time()) . ' using the auth-PHP SDK quickstart!', 91 | ], 92 | ]); 93 | 94 | if (! HttpResponse::wasSuccessful($response)) { 95 | exit('Management API request failed. Unable to update user.'); 96 | } 97 | 98 | return HttpResponse::decodeContent($response); 99 | } 100 | 101 | public function setup(): self 102 | { 103 | // Register our example hook to override the default quickstart onLoginRoute behavior: 104 | $this->app->hook('onIndexRoute', fn (\Auth0\Quickstart\ApplicationRouter $router, ?stdClass $session): ?bool => $this->onIndexRoute($router, $session)); 105 | 106 | return $this; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/src/Example/PasswordlessMagic.php: -------------------------------------------------------------------------------- 1 | app = &$app; 26 | } 27 | 28 | public function onCallbackRoute( 29 | ApplicationRouter $router, 30 | ): bool { 31 | // @phpstan-ignore-next-line 32 | $passwordlessState = $_GET['passwordless'] ?? null; 33 | 34 | // @phpstan-ignore-next-line 35 | $hash = $_GET['hash'] ?? null; 36 | 37 | if ('complete' === $passwordlessState) { 38 | $this->app->getSdk()->exchange($router->getUri('/', '')); 39 | $router->redirect($router->getUri('/', '')); 40 | } 41 | 42 | if (null === $hash) { 43 | $this->app->getTemplate()->render('passwordless-magic-callback'); 44 | 45 | return true; 46 | } 47 | 48 | $params = explode('&', urldecode($hash)); 49 | 50 | foreach ($params as $index => $param) { 51 | [$key, $value] = explode('=', $param); 52 | $params[$key] = $value; 53 | unset($params[$index]); 54 | } 55 | 56 | $accessToken = $params['access_token'] ?? null; 57 | $scope = $params['scope'] ?? null; 58 | $expiresIn = $params['expires_in'] ?? null; 59 | 60 | if (null === $accessToken || null === $scope || null === $expiresIn) { 61 | $router->redirect($router->getUri('/', '')); 62 | 63 | return true; 64 | } 65 | 66 | // Authentication was successful. For some applications, this access token may be enough for your needs. 67 | // For the purposes for this quickstart, we'll redirect back to Auth0 using 'silent authentication' (prompt=none) to get an Id Token. 68 | $router->redirect($this->app->getSdk()->login($router->getUri('/callback', 'passwordless=complete'), ['prompt' => 'none'])); 69 | 70 | return true; 71 | } 72 | 73 | public function onLoginRoute( 74 | ApplicationRouter $router, 75 | ): bool { 76 | $startedPasswordless = false; 77 | 78 | if ('POST' === $router->getMethod()) { 79 | // @phpstan-ignore-next-line 80 | $email = filter_var($_POST['passwordless_email'], FILTER_SANITIZE_EMAIL); 81 | 82 | if (false === $email) { 83 | $router->redirect($router->getUri('/', '')); 84 | 85 | return true; 86 | } 87 | 88 | $response = $this->app->getSdk()->authentication()->emailPasswordlessStart($email, 'link', [ 89 | 'redirect_uri' => $router->getUri('/callback', ''), 90 | 'scope' => $this->app->getConfiguration()->formatScope(), 91 | ]); 92 | 93 | if (! HttpResponse::wasSuccessful($response)) { 94 | $response = HttpResponse::decodeContent($response); 95 | 96 | $error = $response['error'] ?? null; 97 | 98 | if ('bad.connection' === $error) { 99 | $error = 'You must enable the "email" passwordless connection in your Auth0 Dashboard for this application first.'; 100 | } else { 101 | $error = $response['error_description'] ?? $response['error'] ?? 'Encountered API error when attempting to start passwordless login.'; 102 | } 103 | 104 | // @phpstan-ignore-next-line 105 | throw new Exception('API Error: ' . (string) $error); 106 | } 107 | 108 | $startedPasswordless = true; 109 | } 110 | 111 | // Display login page, prompting for email address: 112 | $this->app->getTemplate()->render('passwordless-magic-login', [ 113 | 'startedPasswordless' => $startedPasswordless, 114 | 'router' => $router, 115 | 'cookies' => $_COOKIE, 116 | ]); 117 | 118 | return true; 119 | } 120 | 121 | public function setup(): self 122 | { 123 | // Register our quickstart example hook to override the default onLoginRoute behavior: 124 | $this->app->hook('onLoginRoute', fn (\Auth0\Quickstart\ApplicationRouter $router): bool => $this->onLoginRoute($router)); 125 | $this->app->hook('onCallbackRoute', fn (\Auth0\Quickstart\ApplicationRouter $router): bool => $this->onCallbackRoute($router)); 126 | 127 | return $this; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /app/templates/_layout.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Auth0 PHP Quickstart for Web Apps 10 | 11 | 24 | 25 | 26 | 27 |28 |74 | 75 | 38 |39 |73 |40 | 63 |64 | 65 |66 | 72 |67 |71 |68 | section('hero')?> 69 |70 |76 | 80 | 81 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /app/templates/error.php: -------------------------------------------------------------------------------- 1 | layout('_layout'); ?> 2 | 3 | start('hero') ?> 4 | 5 | Error 6 | PHP Quickstart 7 | 10 | 11 | 12 |77 | section('body')?> 78 |79 |13 | Oops! 14 | 15 |
16 | 17 |Raised on line of .
18 | stop() ?> 19 | 20 | start('body') ?> 21 |22 | 34 | 35 |95 | stop() ?> 96 | -------------------------------------------------------------------------------- /app/templates/logged-in.php: -------------------------------------------------------------------------------- 1 | layout('_layout'); ?> 2 | 3 | start('hero') ?> 4 | 5 | Logged In 6 | PHP Quickstart 7 | 10 | 11 | 12 |36 | 37 |94 |38 |54 | 55 | 56 | 93 |39 |53 |40 |52 |41 | 44 |45 |46 |51 |Local Development Tip
47 |48 |50 |You appear to be running this quickstart on your local machine. Please ensure you are being consistent in your use of localhost and/or 127.0.0.1, as this is the most common pitfall for new developers hitting errors. Make sure the Quickstart and Auth0 are configured to use the same address to avoid authentication errors, and that you're using the same address in your browser to ensure cookies can be set properly.
49 |13 | Welcome 14 | 15 | user['picture'])): ?> 16 | 17 |
24 | 25 |18 | 19 | 20 | 21 | user['email'] ?> 22 | 23 |
You successfully authenticated as user['sub'] ?>.
26 | stop() ?> 27 | 28 | start('body') ?> 29 |30 | 60 | 61 |170 | stop() ?> 171 | -------------------------------------------------------------------------------- /app/templates/logged-out.php: -------------------------------------------------------------------------------- 1 | layout('_layout'); ?> 2 | 3 | start('hero') ?> 4 | 5 | Logged Out 6 | PHP Quickstart 7 | 10 | 11 | 12 |62 |169 |63 |92 | 93 |64 |91 |65 |90 |66 |69 | 70 |User Information
67 |Retrieve these details using Auth0::getCredentials() or Auth0::getUser().
68 |71 | user as $key => $data): ?> 72 | 73 | 74 | 75 |89 |76 | 77 | 78 |79 | 80 | 81 | 82 |83 | 84 | 85 |86 | 87 | 88 |94 |130 | 131 | 168 |95 |129 |96 |128 |97 |100 | 101 |Credentials
98 |Retrieve these using Auth0::getCredentials(), or Auth0::getIdToken(), Auth0::getAccessToken(), Auth0::getAccessTokenScope(), Auth0::getAccessTokenExpiration(), and Auth0::getRefreshToken() respectively.
99 |102 |127 |103 | 104 | 105 |106 | 107 |108 | 109 | 110 |111 | 112 |113 | 114 | 115 |116 | 117 |118 | 119 | 120 |121 | 122 |123 | 124 | 125 |126 |13 | Welcome, 14 | Guest 15 |
16 | 17 |You are not authenticated.
18 | stop() ?> 19 | 20 | start('body') ?> 21 |22 | 34 | 35 |75 | stop() ?> 76 | -------------------------------------------------------------------------------- /app/templates/management.php: -------------------------------------------------------------------------------- 1 | layout('_layout'); ?> 2 | 3 | start('hero') ?> 4 | 5 | Logged In 6 | PHP Quickstart 7 | 10 | 11 | 12 |36 |74 | 73 |13 | Welcome 14 | 15 | user['picture'])): ?> 16 | 17 |
24 | 25 |18 | 19 | 20 | 21 | user['email'] ?> 22 | 23 |
You successfully authenticated as user['sub'] ?>.
26 | stop() ?> 27 | 28 | start('body') ?> 29 |30 | 60 | 61 |198 | stop() ?> 199 | -------------------------------------------------------------------------------- /app/templates/passwordless-magic-callback.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/templates/passwordless-magic-login.php: -------------------------------------------------------------------------------- 1 | layout('_layout'); ?> 2 | 3 | start('hero') ?> 4 | 5 | Logged Out 6 | PHP Quickstart 7 | 10 | 11 | 12 |62 |197 |63 |75 | 76 | 89 | 90 |64 |74 |65 |73 |66 |68 | 69 |Management API GET /api/v2/users/{id}
67 |70 | 71 |72 |91 |120 | 121 |92 |119 |93 |118 |94 |97 | 98 |User Information
95 |Retrieve these details using Auth0::getCredentials() or Auth0::getUser().
96 |99 | user as $key => $data): ?> 100 | 101 | 102 | 103 |117 |104 | 105 | 106 |107 | 108 | 109 | 110 |111 | 112 | 113 |114 | 115 | 116 |122 |158 | 159 | 196 |123 |157 |124 |156 |125 |128 | 129 |Credentials
126 |Retrieve these using Auth0::getCredentials(), or Auth0::getIdToken(), Auth0::getAccessToken(), Auth0::getAccessTokenScope(), Auth0::getAccessTokenExpiration(), and Auth0::getRefreshToken() respectively.
127 |130 |155 |131 | 132 | 133 |134 | 135 |136 | 137 | 138 |139 | 140 |141 | 142 | 143 |144 | 145 |146 | 147 | 148 |149 | 150 |151 | 152 | 153 |154 |13 | Welcome, 14 | Guest 15 |
16 | 17 |You are not authenticated.
18 | stop() ?> 19 | 20 | start('body') ?> 21 |22 | 43 | 44 |127 | stop() ?> 128 | -------------------------------------------------------------------------------- /app/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | toBeTrue(); 5 | }); 6 | -------------------------------------------------------------------------------- /app/tests/Pest.php: -------------------------------------------------------------------------------- 1 | in('Feature'); 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Expectations 19 | |-------------------------------------------------------------------------- 20 | | 21 | | When you're writing tests, you often need to check that values meet certain conditions. The 22 | | "expect()" function gives you access to a set of "expectations" methods that you can use 23 | | to assert different things. Of course, you may extend the Expectation API at any time. 24 | | 25 | */ 26 | 27 | expect()->extend('toBeOne', function () { 28 | return $this->toBe(1); 29 | }); 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Functions 34 | |-------------------------------------------------------------------------- 35 | | 36 | | While Pest is very powerful out-of-the-box, you may have some testing code specific to your 37 | | project that you don't want to repeat in every file. Here you can also expose helpers as 38 | | global functions to help you to reduce the number of lines of code in your test files. 39 | | 40 | */ 41 | 42 | function something() 43 | { 44 | // .. 45 | } 46 | -------------------------------------------------------------------------------- /app/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | toBeTrue(); 5 | }); 6 | --------------------------------------------------------------------------------45 | 46 |126 |47 |63 | 64 | 65 | 87 | 88 | 125 |48 |62 |49 |61 |50 | 53 |54 |55 |60 |Email Sent!
56 |57 |59 |Check your inbox and click the link to continue logging in.
58 |