2017-09-03 131 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代码中,这不会导致令牌在传递到页面时被暴露吗?你有没有举例说明我提供的示例代码将如何修改以适用于您提出的解决方案? –