public function actionToken() { // Load data from post and validate. $codeForm = new CodeForm(['scenario' => CodeForm::SCENARIO_VERIFY]); $codeForm->load(Yii::$app->request->post(), ''); if (!$codeForm->validate()) { // Throw the first error. $error = 'unknown'; $errors = $codeForm->getErrors(); foreach ($errors as $ek => $ev) { $error = $ev[0]; break; } throw new BadRequestHttpException($error); } // Attempt to load the code from the database. $authCode = Oauth2Code::findCodeOnce($codeForm->code); if (!$authCode) { throw new BadRequestHttpException('Invalid code'); } // Create new auth token with the user and scope of the token. $authToken = new Oauth2Token($authCode->user_id, $authCode->scope); $authToken->save(); $expireTime = $authToken->getExpiration(); // Create the respone data. $data = ['access_token' => $authToken->token, 'token_type' => 'bearer']; // Add expire durection if it expires. if ($expireTime >= 0) { $data['expires_in'] = $expireTime; } return $data; }
/** * Get the redirect URL using either data if valid, or session data. * Existing session data will be cleared on call, even with valid data. * This is to ensure that session-based redirects only happen once. * Also handles all validation and token code creation. * * @param array|null $data Data to use if valid. * @param array|null $auto Automatic redirect. * @return string|null Redirect URI with parameters, or null. */ public static function getSessionRedirectLocation($data = null, $auto = true) { // Only works if authenticated. if (Yii::$app->user->isGuest) { return null; } $user = Yii::$app->user->identity; // If data does not contain cliend_id, load data from session. if (!isset($data['client_id'])) { // Read data from session, then clear. $data = static::getSessionRedirect(); } // If must allow auto and set to not do auto, return null. if ($auto && isset($data[static::SSO_REDIRECT_NO_AUTO_KEY])) { return null; } // Remove any session redirect on auto, only ever redirect once, code expires. static::setSessionRedirect(null); // Check if data contains the minimal parameters before continuing. if (!isset($data['client_id'], $data['redirect_uri'])) { return null; } $model = new CodeForm(['scenario' => CodeForm::SCENARIO_CREATE]); $model->load($data, ''); if (!$model->validate()) { // Throw the first error. $error = 'unknown'; $errors = $model->getErrors(); foreach ($errors as $ek => $ev) { $error = $ev[0]; break; } throw new BadRequestHttpException($error); } // Create single use code for the user and the scope. $authcode = new Oauth2Code($user->id, $model->scope); $authcode->save(); // Set the code on the model and generate the URL. $model->code = $authcode->code; return $model->redirectURL(); }