阻止除前端之外的任何其他资源的 API 访问

问题描述 投票:0回答:6

我有一条路线

api/v1/track
,我想通过给定的轨道ID发送一些数据(JSON),但我只想发送我的前端请求或我的移动应用程序的响应,而不是来自任何地方的任何其他请求!

我正在使用 Node JS 和 Express,我实现了一些 JWT 配置来使用令牌对用户进行身份验证,但我不知道如何在没有任何预先创建的令牌的情况下限制此路由的访问

app.get("/track/:ID" , (req , res) => {

    // Block forbidden requests ... 

    // If request is from my specific resource ( Frontend or App ) then : 
    res.json(something)
}) 

我只是不想让人们使用我的 API 信息,我还需要在用户进行身份验证之前将数据发送到我的 Vue SPA

谢谢你

node.js api http security jwt
6个回答
25
投票

没有通用方法可以将 API 的使用仅限于您自己的网页。网络上的 API 是“在网络上”,网络上的任何编程工具都可以访问它。

正如其他人所说,您可以实现 COR 保护,但这只能阻止人们在自己的网页中通过自己的 Javascript 访问您的 API - 它不会阻止其他脚本或编程工具(如curl)访问您的 API。 COR 是一种客户端保护,仅在现代浏览器中强制执行。 COR 不适用于访问 API 的其他方式,例如通过脚本或其他编程工具。

这里唯一真正的解决方案是对所有 API 请求实施身份验证,然后保护您的服务器免遭 API 的滥用。身份验证背后的想法是,在 API 提供任何结果之前,您需要某种经过身份验证的登录/帐户。为了在您自己的网页中使用,您可能拥有某种可用于身份验证的登录名。

然后,在服务器上,您需要每次 API 调用来检查是否存在登录凭据,例如经过验证的登录 cookie、经过验证的 JWT 令牌等...

这会阻止公开使用您的 API,但显然人们仍然可以在您的网站上创建帐户,然后使用这些凭据以编程方式使用您的 API。控制这种情况的唯一方法是实施服务器端保护,例如速率限制,以防止滥用 API,从而影响服务器的质量或响应能力。

对于 Google 等地方的 API 服务器,它们通常会要求您注册某种开发者帐户并获取一些 API 访问凭据,然后您可以将其与 API 一起使用。作为其中的一部分,您必须同意他们的服务条款,如果您违反这些服务条款,他们可以撤销您的 API 凭证。他们还会通过速率限制来主动控制您的访问,在某些情况下还会限制带宽使用。


0
投票

我有同样的问题,我正在考虑在我的前端生成某种令牌,服务器会验证并且只能使用一次,所以假设攻击者想要使用以前使用过的令牌来攻击端点,我的服务器会检测到它已被使用,从而阻止请求。换句话说,我的前端每次发出请求时都会生成一个特殊的令牌。


-1
投票

您可以使用 CORS 来限制对您服务器的访问,换句话说,您可以“告诉应用程序可以从哪个 URL 以及哪些方法进行访问”。有很好的文档。 在手机上,它仅适用于混合应用程序(Cordova/Ionic/Phonegap 等),因为它们使用浏览器。


-1
投票

这是我经常问自己的一个问题,基本上我所做的就是每次进入一家大公司网站(ebay、facebook 等...)时,我打开 chrome devtools 网络选项卡,看看那里发生了什么并从中获得灵感,但很难理解正在发生的事情(至少对我来说)。 我实现的另一个解决方案是,我在前端使用了 Google reCaptchaV2(假设您仅针对 POST/PATCH 请求调用 api),因此在我的服务器上,我总是检查 reCaptcha 令牌是否存在且有效,如果不是,请求就会被拒绝。


-2
投票

正如 @Marcos Molina 的回复中提到的,您必须在 API 中使用 CORS 设置

Express 文档可在此处

找到

下面是来自 Github

上随机人员项目的基本示例

*
可以替换为您想要的前端客户端域

CORS 通用文档此处

import http from 'http';
import bodyParser from 'body-parser';
import express from 'express';
import logging from './config/logging';
import config from './config/config';
import sampleRoutes from './routes/sample';

const NAMESPACE = 'Server';
const router = express();

// ...

/** Rules of our API */
router.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');

    if (req.method == 'OPTIONS') {
        res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
        return res.status(200).json({});
    }

    next();
});

/** Routes go here */
router.use('/api/sample', sampleRoutes);

// ...

const httpServer = http.createServer(router);

httpServer.listen(config.server.port, () => logging.info(NAMESPACE, `Server is running ${config.server.hostname}:${config.server.port}`));

-3
投票

我猜想一个选项可能是限制后端仅通过前端的 IP 进行请求。例如,如果前端的 IP 为“1.2.3.4”,则应阻止来自其他 IP 的所有请求。

© www.soinside.com 2019 - 2024. All rights reserved.