2017-09-03 133 views
0

以下腳本使用簡單的AJAX和Javascript將信息從API中查詢並輸出到HTML中。在JavaScript中傳遞API令牌:如何保持安全

API的TOKEN在Javascript中公開。在我看來,這是不安全的,因爲任何可以訪問該頁面的人都可以看到令牌。如果這個方法不安全,是否有一些額外的方法來隱藏令牌?理想情況下,如果需要,我想使用Javascript,HTML和PHP。現有的腳本非常簡單,所以我想知道是否有一種相對簡單的方法來保護令牌..而不是增加許多額外的新代碼或方法。

<html> 
<body> 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 

<script> 
    var settings = { 
    "async": true, 
    "crossDomain": true, 
    "url": "https://www.eventbriteapi.com/v3/events/eventid/? 
token=TOKEN", 
    "method": "GET", 
    "headers": {} 
    } 

    $.ajax(settings).done(function (data) { 
    console.log(data); 
    var content = "<h2>" + data.name.text + "</h2>" + data.description.html + 
data.start.utc; 
    $("#eventbrite").append(content); 
    }); 
</script> 

<div id="eventbrite"></div> 

</body> 
</html> 
+0

肯定它不是固定到從客戶端調用私有API,而應該叫'你server',然後您的服務器可以調用'eventbrite' api .. – webdeb

+0

在您的站點上創建一個php腳本,用於處理實際的遠程站點調用並使用ajax發送e請求到您的本地php腳本(所以它的行爲或多或少像一個代理) – RamRaider

+0

不僅您的「祕密」密鑰在瀏覽器中不能保密,而且最重要的是,域請求。解決您的問題的唯一方法是使用服務器,而不是瀏覽器。 –

回答

1

可以使用PHP讓你的服務器上的一個簡單的代理腳本!然後

你的JavaScript將調用這個腳本,包括在GET參數的事件ID,沒有別的,所以調用你的PHP代理會是這樣/proxy.php?eventid=123

爲了進一步fancify這個例子中,你可以利用$_SESSION等,使確保您的用戶在訪問之前訪問了該頁面,並且只允許每個頁面載入1個請求或類似的請求。

我準備了一個樣本,但您必須修改它以符合您的需求!

<?php 

//Get event ID you want to request: 
$eventID = isset($_GET['eventid']) ? $_GET['eventid'] : FALSE; 

//Exit if no ID provided: 
if (!$eventID) { 
    exit('No ID Provided.'); 
} 

//Set your token: 
$token = '<YOUR_TOKEN_HERE>'; 

//Set url, %s will be replaced later: 
$url = 'https://www.eventbriteapi.com/v3/events/%s/?token=%s'; 

//Set url, pass in params: 
$request_uri = sprintf($url, $eventID, $token); 

//Try to fetch: 
$response = file_get_contents($request_uri); 

//Set content-type to application/json for the client to expect a JSON response: 
header('Content-type: application/json'); 

//Output the response and kill the scipt: 
exit($response); 

資源: What is a Proxy (Wikipedia)

更新: 的JavaScript:

$.getJSON('/proxy.php', {eventid: '<id_here>'}, function(response){ 
    console.log(response); 
    var content = "<h2>" + data.name.text + "</h2>" + data.description.html + 
    data.start.utc; 
    $("#eventbrite").append(content); 
}); 
+0

謝謝,這非常有用。對於現有的var設置,我試圖修改這些參數來連接到PHP腳本而不是外部URL,比如URL = proxy.php?eventid = 123 ..但是想知道是否該腳本還需要進一步修改才能工作有了這個新的設置? –

+1

@DanielC我已經更新了我的答案,其中包含一些javascript示例代碼:) –

+0

哇謝謝!有沒有我需要的其他JavaScript?當我用你的腳本替換我的腳本時,控制檯中出現'數據未定義'的錯誤 –

0

您可能不應該存儲API密鑰客戶端,爲什麼不把它存儲在JS調用的PHP腳本中?

如果你真的堅持存儲它的客戶端,你一定要加密它,但我不想依賴於它。

+0

這只是將問題移到服務器。現在,攻擊者所要做的就是擊中服務器上的PHP腳本,而不是使用令牌的API。 – BenM

+0

我認爲我們對OP的目標有不同的看法。我假設OP有一個面向公衆的API,它依賴於對其他API的調用,並且他目前正在存儲其他API令牌客戶端。這是不安全的。如果他將其移入服務器上面向公衆的API腳本中,則其他API令牌現在是安全的。看來你理解的情況是,這個API令牌是爲用戶提供對OPs服務器端API的訪問,但是如果是這種情況,那麼存儲關鍵客戶端沒有任何問題,除非它不是每個客戶端都是獨一無二的(但那就是問題所在)。 – jconder

0

將您的API密鑰存儲到服務器並在需要時向其請求。爲了讓服務器端更安全,只有在您傳遞並驗證令牌(已設置)以防止欺騙AJAX請求時才返回API密鑰。

例如:

PHP

/** Change $_POST respectively to what you need. **/ 
if (isset($_POST['request_api_key_token']) && $_POST['request_api_key_token'] == 'your_value') { 
    /** Return your API key. **/ 
} else { 
    exit(header('HTTP/1.0 403 Forbidden')); 
} 
+1

我很難跟着這個。如果我將API密鑰存儲在服務器上,在PHP腳本中,那麼我調用一個函數來將令牌放入上面的Javascript代碼中,這不會導致令牌在傳遞到頁面時被暴露嗎?你有沒有舉例說明我提供的示例代碼將如何修改以適用於您提出的解決方案? –