。對於服務器端,應該被驗證。
SDK的是(在作曲家)(代碼如下):
- Facebook的:
"facebook/php-sdk-v4" : "4.0.*"
- 谷歌:
cURL
請求(不關心"google/apiclient"
)
- 的SoundCloud:
"ise/php-soundcloud": "3.*"
(當然還有其他的,這三個是我選擇的,看起來很體面。)
上次我做了這樣的事情,我犯了一個錯誤,在每個請求上驗證access_token
,這對性能有巨大的(顯然是負面的)影響。現在我只是在登錄時驗證它並使用它從該服務中檢索用戶的ID。所以,瀏覽器發給我access_token A
,並說它來自Facebook,我使用Facebook上面的access_token
上面的sdk,並且我取回他們的ID,所以我知道他們是誰,他們是誰。
我建議在expires_in
服務器上存儲access_token
。
(我沒有處理刷新令牌的又)
代碼使用上述庫來驗證令牌:
function validateTokenFacebook($token, $id=null) {
// Performed above
// FacebookSession::setDefaultApplication($config->fb->app_id, $config->fb->secret);
$session = new FacebookSession($token);
// Fetch user info
$request = new FacebookRequest($session, 'GET', '/me');
try {
$response = $request->execute();
} catch (\Facebook\FacebookServerException $e) {
$this->mlog->err($e . "\n" . $e->getTraceAsString());
throw new AuthTokenInvalidException();
}
$graphObject = $response->getGraphObject();
$user_id = $graphObject->getProperty('id');
return array(access_token, $user_id);
}
function validateTokenGoogle($token, $id=null) {
$resp=array();
// This key isn't included in the token from hello.js, but
// google needs it
if (!array_key_exists('created', $token)) $token['created'] = $token['expires'] - $token['expires_in'];
$client = new \Google_Client();
$client->setClientId($this->systemConfig->google->app_id);
$client->setClientSecret($this->systemConfig->google->secret);
$client->setRedirectUri($this->systemConfig->google->redirectUri);
$client->setScopes('email');
$client->setAccessToken(json_encode($token));
try {
// Send Client Request
$objOAuthService = new \Google_Service_Oauth2($client);
$userData = $objOAuthService->userinfo->get();
return array($token['access_token'], $userData['id']);
} catch (\Google_Auth_Exception $e) {
throw new AuthException('Google returned ' . get_class($e));
}
}
function validateTokenSoundcloud($token, $id=null) {
$soundcloud = new \Soundcloud\Service(
$this->systemConfig->soundcloud->app_id,
$this->systemConfig->soundcloud->secret,
$this->systemConfig->soundcloud->redirect);
$soundcloud->setAccessToken($access_token);
try {
$response = json_decode($soundcloud->get('me'), true);
if (array_key_exists('id', $response))
return array($access_token, $response['id']);
} catch (Soundcloud\Exception\InvalidHttpResponseCodeException $e) {
$this->mlog->err($e->getMessage());
}
throw new AuthTokenInvalidException();
}
我有以上幾個自定義類,如異常和systemConfig,但我認爲它足夠詳細以傳達他們所做的事情。
因此,如果我明白了,我可以將足夠的內容放入JWT中,以證明用戶已通過身份驗證?即它將包含一個帶有令牌的電子郵件,該令牌只能由服務X創建;並提供JWT是合法的,系統會知道它包含真正的信息?那麼我的系統就不需要獨立地調用Google/FB/etc了? (現在閱讀博客文章) – Matt
是的。 JWT是一個自包含的實體,包含關於用戶的信息:(例如姓名,電子郵件)或與您的API有關的用戶(例如,用戶是「管理員」)。它是數字簽名的,所以你可以檢查完整性。你可以在後臺檢查簽名而不需要額外的服務器請求,它只是一個加密函數。 –
我仍然不明白這可能是絕對安全的。我遵循你的博客文章中的建議(真的很有幫助!)我認爲讓這個安全的唯一方法是讓服務器使用它接收的access_token並根據服務(google/fb/...)進行查詢。最安全的方式我可以想象的是,使用一個鍵(例如電子郵件)作爲索賠中的「子」,並將用戶標識作爲祕密來形成智威湯遜(如您所建議的)。但即使這可能是假的。 – Matt