clientId = $clientId; $this->clientSecret = $clientSecret; $this->redirectUri = $redirectUri; $this->setStore($store ? $store : new BaiduCookieStore($clientId)); } /** * Get an instance of BaiduOAuth2 class. * * @return BaiduOAuth2 */ public function getBaiduOAuth2Service() { if (!$this->oauth2) { $this->oauth2 = new BaiduOAuth2($this->clientId, $this->clientSecret); $this->oauth2->setRedirectUri($this->redirectUri); } return $this->oauth2; } /** * Get an instance of BaiduApiClient class. * * @param string $accessToken Access token for api calls. * @return BaiduApiClient */ public function getBaiduApiClientService() { return new BaiduApiClient($this->clientId, $this->getAccessToken()); } /** * Get access token for openapi calls. * * @return string|false Returns access token if user has authorized the app, or false if not. */ public function getAccessToken() { $session = $this->getSession(); if (isset($session['access_token'])) { return $session['access_token']; } else { return false; } } /** * Get refresh token. * * @return string|false Returns refresh token if app has, or false if not. */ public function getRefreshToken() { $session = $this->getSession(); if (isset($session['refresh_token'])) { return $session['refresh_token']; } else { return false; } } /** * Get currently logged in user's uid. * * @return uint|false Return uid of the loggedin user, or return * false if user isn't loggedin. */ public function getLoggedInUser() { // Get user from cached data or from access token $user = $this->getUser(); // If there's bd_sig & bd_user parameter in query parameters, // it must be an inside web app(app on baidu) loading request, // then we must check whether the uid passed from baidu is the // same as we get from persistent data or from access token, // if it's not, we should clear all the persistent data and to // get an access token again. if (isset($_REQUEST['bd_sig']) && isset($_REQUEST['bd_user'])) { $params = array('bd_user' => $_REQUEST['bd_user']); $sig = BaiduUtils::generateSign($params, $this->clientSecret, 'bd_sig'); if ($sig != $_REQUEST['bd_sig'] || $user['uid'] != $_REQUEST['bd_user']) { $this->store->remove('session'); return false; } } return $user; } /** * Get a Login URL for use with redirects. By default, full page redirect is * assumed. If you are using the generated URL with a window.open() call in * JavaScript, you can pass in display=popup as part of the $params. * * @param string $scope blank space separated list of requested extended perms * @param string $display Authorization page style, 'page', 'popup', 'touch' or 'mobile' * @return string the URL for the login flow */ public function getLoginUrl($scope = '', $display = 'page') { $oauth2 = $this->getBaiduOAuth2Service(); return $oauth2->getAuthorizeUrl('code', $scope, $this->state, $display); } /** * Get the Logout URL suitable for use with redirects. * * @param string $next Url to go to after a successful logout. * * @return string */ public function getLogoutUrl($next) { $oauth2 = $this->getBaiduOAuth2Service(); return $oauth2->getLogoutUrl($this->getAccessToken(), $next); } /** * Get user session info. * * @return array */ public function getSession() { if ($this->session === null) { $this->session = $this->doGetSession(); } return $this->session; } /** * Set user session. * * @param array $session User session info. * @return Baidu */ public function setSession($session) { $this->session = $session; if ($session) { $this->store->set('session', $session); } else { $this->store->remove('session'); } return $this; } /** * Get current user's uid and uname. * * @return array|false array('uid' => xx, 'uname' => xx) */ protected function getUser() { $session = $this->getSession(); if (is_array($session) && isset($session['uid']) && isset($session['uname'])) { return array('uid' => $session['uid'], 'uname' => $session['uname']); } else { return false; } } /** * Set the session data storage instance. * * @param BaiduStore $store * @return Baidu */ protected function setStore($store) { $this->store = $store; if ($this->store) { $state = $this->store->get('state'); if (!empty($state)) { $this->state = $state; } //as the storage engine is changed, we need to get the session again. $this->session = null; $this->getSession(); $this->establishCSRFTokenState(); } return $this; } /** * Get session info from Baidu server or from the store in app server side. * * @return array|false */ protected function doGetSession() { // get authorization code from query parameters $code = $this->getCode(); // check whether it is a CSRF attack request if ($code && $code != $this->store->get('code')) { $oauth2 = $this->getBaiduOAuth2Service(); $session = $oauth2->getAccessTokenByAuthorizationCode($code); if ($session) { $this->store->set('code', $code); $this->setSession($session); $apiClient = new BaiduApiClient($this->clientId, $session['access_token']); $user = $apiClient->api('passport/users/getLoggedInUser'); if ($user) { $session = array_merge($session, $user); $this->setSession($session); } return $session; } // code was bogus, so everything based on it should be invalidated. $this->store->removeAll(); return false; } // as a fallback, just return whatever is in the storage $session = $this->store->get('session'); $this->setSession($session); if ($session && !isset($session['uid'])) { $apiClient = new BaiduApiClient($this->clientId, $session['access_token']); $user = $apiClient->api('passport/users/getLoggedInUser'); if ($user) { $session = array_merge($session, $user); $this->setSession($session); } } return $session; } /** * Get the authorization code from the query parameters, if it exists, * otherwise return false to signal no authorization code was discoverable. * * @return mixed Returns the authorization code, or false if the authorization * code could not be determined. */ protected function getCode() { if (isset($_GET['code'])) { if ($this->state && $this->state === $_GET['state']) { // CSRF state has done its job, so clear it $this->state = null; $this->store->remove('state'); return $_GET['code']; } else { BaiduUtils::errorLog('CSRF state token does not match one provided.'); return false; } } return false; } /** * Lays down a CSRF state token for this process. * * @return void */ protected function establishCSRFTokenState() { if ($this->state === null) { $this->state = md5(uniqid(mt_rand(), true)); $this->store->set('state', $this->state); } } }