2016-02-21 65 views
2

我的應用程序由幾個可通過AJAX訪問的PHP端點組成。問題是他們也可以通過向相同端點發出HTTP請求的任何人訪問。我可以添加this answer中指定的HTTP_X_REQUESTED_WITHHTTP_REFERER的支票,但這些可能是欺騙性的。我可以添加一個需要與請求一起發佈的密鑰,但任何查看javascript和/或控制檯的人都可以看到此密鑰。這裏有什麼解決方案?保護由AJAX調用的PHP端點

+0

你在擔心什麼? CSRF?如果是這樣,一個令牌就是答案。不管它是否是Ajax都沒關係。 – weltschmerz

+1

不,我只是不希望(例如)端點(如「deleteJob」)被惡意人員/工具調用,只能由端點駐留在服務器上的實際網站調用。 – GluePear

+0

如果端點是公開的,任何人都可以調用它,Ajax或不。你需要認證。 – weltschmerz

回答

3

人們經常認爲,因爲他們正在使用Ajax請求,常規sessions不起作用。他們是這樣。 如果你有一個端點從數據庫中刪除的東西,是在源代碼中可見,如:

example.com/user/1/delete 

可以防止非認證用戶的這一要求,你會使用非Ajax的HTTP請求時,以同樣的方式在瀏覽器中。使用sessions。如果用戶具有刪除用戶的權限,則此路由將起作用,否則返回錯誤(或不執行任何操作)。

您還可以使用OAuth保護API。這裏有一個很好的文檔解釋了它是如何工作的:http://tatiyants.com/using-oauth-to-protect-internal-rest-api/

+0

會話將不能跨域使用。例如,如果您的應用在'app.example.com'上運行,並且您的API在'api.example.com'上運行,則不會有可用的會話。 –

2

沒有一個。如果你給某人一些數據,那麼他們可以用任何他們喜歡的方式處理它。您無法控制它離開您的服務器後會發生什麼。

同樣,您無法控制它們發送到端點的數據。

+0

準確。任何你給/從瀏覽器提供的信息都可以被任何攻擊者用腦,使用,修改和操縱。 – ceejayoz

+0

所以說我有一個叫做「deleteJob」的端點,我希望前端/客戶端可以訪問它,但是沒有辦法保護它? – GluePear

+0

有,通過認證,然後可能授權規則。身份驗證可以通過客戶端需要發送的客戶端上存儲的cookie或令牌來完成。 – weltschmerz

0

開發人員對API或Web服務進行身份驗證非常重要。 dchackeBugHunterUK給了完美的答案,我只是想告訴你簡單的代碼,我用它來製作非常簡單和易於使用的身份驗證。

添加會話的認證

你可以爲你的API添加會話,會話超時等等,只有你的應用程序可以利用這一點,你就可以開始會話時加載的應用程序的頭版,你可以設置超時時間,並通過會話限制不同用戶的不同服務。

總體思路如何做到這一點

<?php 
if(!empty($_SESSION['api_session']) && $_SESSION['api_session'] == 'usertype'){ 
//usertype comprise of what access you want to give 
//guest, registered user, stack holder, admin etc. 
... 
header('Content-Type:application/json;'); 
echo json_encode($output); 
} 
2

大部分的答案是沒有幫助的,如果你有你的應用程序和您單獨的域API例如app.example.comapi.example.com - 在這種情況下,會議將無法工作,你將不得不轉向OAuth,這對於這樣一個簡單的問題來說是一個相當大的錘子。

這裏是我會做什麼:

我假設你有一個數據庫和一個唯一的標識符像user_id=12345用戶。我還假設你在數據庫中有工作,他們也有唯一的ID,如job_id=6789

首先對app.example.com你的東西快速和容易像河豚加密兩個標識:

$secret_uid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($user_id)); 
$secret_jid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($job_id)); 

我假設你的終點會有點像這樣工作:

api.example.com/jobs/delete/<job_id>/<user_id> 

所以現在從阿賈克斯你把那個叫但終點,而不是用普通的ID叫

api.example.com/jobs/delete/6789/12345 

你CA與經過加密的ID LL它:

api.example.com/jobs/delete/6A73D5B557C622B3/57F064C07F83644F 

在您的軟件API方面,你解密參數:

$jid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_1>); 
$uid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_2>); 

現在,你可以搜索你的分貝uidjid和執行的任何任務,你正計劃去做。確保用戶只能刪除自己的工作,當然。我承認這不是一個100%的解決方案,但是它給攻擊者留下了大量的猜測工作 - 他將不得不猜測user_id和匹配的job_id,加密算法和祕密。它不能防止數百萬次蠻力企圖猜測匹配的對,但它會給你帶來好處(而且你應該對你的端點有一些配額限制保護)。

祝你好運!