public function login() { $user = $this->Auth->identify(); if (!$user) { $this->set(['success' => false, 'message' => __('Invalid email or password'), '_serialize' => ['success', 'message']]); } else { $expire = !is_null(Configure::read('AuthToken.expire')) ? Configure::read('AuthToken.expire') : 3600; $access_token = JWT::encode(['sub' => $user['id'], 'exp' => time() + $expire], Security::salt()); $refresh_token = JWT::encode(['sub' => $user['id'], 'ref' => time()], Security::salt()); $authToken = $this->Users->AuthToken->newEntity(); $authToken->user_id = $user['id']; $authToken->access_token = $access_token; $authToken->refresh_token = $refresh_token; $this->Users->AuthToken->save($authToken); $this->set(['success' => true, 'data' => ['access_token' => $access_token, 'refresh_token' => $refresh_token, 'id' => $user['id'], 'username' => $user['username'], 'email' => $user['email']], '_serialize' => ['success', 'data']]); } }
public function token() { if ($this->request->is('post')) { $table = TableRegistry::get('AuthToken'); $refresh_token = $this->request->data('refresh_token'); $authToken = $table->find('all')->where(['refresh_token' => $refresh_token])->first(); if ($authToken) { $expire = !is_null(Configure::read('AuthToken.expire')) ? Configure::read('AuthToken.expire') : 3600; $access_token = JWT::encode(['sub' => $authToken['user_id'], 'exp' => time() + $expire], Security::salt()); $refresh_token = JWT::encode(['sub' => $authToken['user_id'], 'ref' => time()], Security::salt()); $authToken->access_token = $access_token; $authToken->refresh_token = $refresh_token; $table->save($authToken); $this->set(['success' => true, 'data' => ['access_token' => $access_token, 'refresh_token' => $refresh_token], '_serialize' => ['success', 'data']]); } else { $this->set(['success' => false, 'refresh_token_expired' => true, '_serialize' => ['success', 'refresh_token_expired']]); } } }
/** * Decodes a JWT string into a PHP object. * * @param string $jwt The JWT * @param string|array|null $key The key, or map of keys. * If the algorithm used is asymmetric, this is the public key * @param array $allowed_algs List of supported verification algorithms * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256' * * @return object The JWT's payload as a PHP object * * @throws DomainException Algorithm was not provided * @throws UnexpectedValueException Provided JWT was invalid * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf' * @throws BeforeValidException Provided JWT is trying to be used before it's been created as defined by 'iat' * @throws ExpiredException Provided JWT has since expired, as defined by the 'exp' claim * * @uses jsonDecode * @uses urlsafeB64Decode */ public static function decode($jwt, $key, $allowed_algs = array()) { if (empty($key)) { throw new InvalidArgumentException('Key may not be empty'); } $tks = explode('.', $jwt); if (count($tks) != 3) { throw new UnexpectedValueException('Wrong number of segments'); } list($headb64, $bodyb64, $cryptob64) = $tks; if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) { throw new UnexpectedValueException('Invalid header encoding'); } if (null === ($payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64)))) { throw new UnexpectedValueException('Invalid claims encoding'); } $sig = JWT::urlsafeB64Decode($cryptob64); if (empty($header->alg)) { throw new DomainException('Empty algorithm'); } if (empty(self::$supported_algs[$header->alg])) { throw new DomainException('Algorithm not supported'); } if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) { throw new DomainException('Algorithm not allowed'); } if (is_array($key) || $key instanceof \ArrayAccess) { if (isset($header->kid)) { $key = $key[$header->kid]; } else { throw new DomainException('"kid" empty, unable to lookup correct key'); } } // Check the signature if (!JWT::verify("{$headb64}.{$bodyb64}", $sig, $key, $header->alg)) { throw new SignatureInvalidException('Signature verification failed'); } // Check if the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. if (isset($payload->nbf) && $payload->nbf > time() + self::$leeway) { throw new BeforeValidException('Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)); } // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). if (isset($payload->iat) && $payload->iat > time() + self::$leeway) { throw new BeforeValidException('Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)); } // Check if refresh token return access t if (isset($payload->ref)) { header('Content-Type:application/json'); $table = TableRegistry::get('AuthToken'); $authToken = $table->find('all')->where(['user_id' => $payload->sub, 'refresh_token' => $jwt])->first(); if ($authToken) { $expire = !is_null(Configure::read('AuthToken.expire')) ? Configure::read('AuthToken.expire') : 3600; $access_token = JWT::encode(['sub' => $authToken['user_id'], 'exp' => time() + $expire], Security::salt()); $refresh_token = JWT::encode(['sub' => $authToken['user_id'], 'ref' => time()], Security::salt()); $authToken->access_token = $access_token; $authToken->refresh_token = $refresh_token; $table->save($authToken); echo json_encode(['success' => true, 'data' => ['access_token' => $access_token, 'refresh_token' => $refresh_token]]); } else { echo json_encode(['success' => false, 'refresh_token_expired' => true]); } exit; } // Check if this token has expired. if (isset($payload->exp) && time() - self::$leeway >= $payload->exp) { //throw new ExpiredException('Expired token'); header('Content-Type:application/json'); echo json_encode(['success' => false, 'access_token_expired' => true]); exit; } return $payload; }