处理来自前端的 API 调用的最佳方式

Posted

技术标签:

【中文标题】处理来自前端的 API 调用的最佳方式【英文标题】:Best way to handle API calls from frontend 【发布时间】:2018-05-30 05:31:27 【问题描述】:

好的,所以 atm 我有一个使用 Nuxt JS 构建的前端应用程序,使用 Axios 向我的 REST API(单独)发出请求。

如果用户在网站上进行搜索,API URL 在 XMLHttprequests 中可见,因此每个人都可以根据需要使用 API。

最好的方法是什么,以便只有通过我的网站搜索的用户才能访问 API,而直接访问 URL 的人会被拒绝。我想使用某种令牌系统,但最好的方法是什么?智威汤逊? (用户从不登录,因此没有“身份验证”)

谢谢!

【问题讨论】:

所以,基本上你要确保人们使用浏览器访问你的 API,如果是这种情况我有坏消息要告诉你,人们总能找到一种方法来绕过它,如果他们愿意,使用一些东西比如 reCAPTCHA 是一种确保真实用户访问您的 API 的方法。 好吧,我想要一种以某种方式限制对 API 的访问的方法。当我将前端托管在单独的端口上时,IP 限制是否可以成为一种方式。所以只允许在同一台机器上从该端口直接调用(例如 API 在 5000 端口上运行,前端应用在 5001 上运行。我可以说只接受来自 5000 的调用吗? 当然,您可以隔离您的 API 以仅接收来自前端应用程序的调用,那么,您将如何避免让非浏览器访问您的前端? 至少前端只返回渲染的组件(带有 Nuxt 的 s-s-r),所以我猜它更难获取数据。然后,您必须抓取该网站。但我想,如果你真的想的话,你仍然可以通过一种或另一种方式获取数据。我只是想让它变得更难,然后只是调用 api 正如我所说,你无法避免它,只会让它变得更难,一种简单的方法是放置 reCAPTCHA。 【参考方案1】:
    IMO,您不能阻止其他非法客户访问您的 后端,正如您所描述的,官方客户和其他非法客户对您的后端有相同的知识。 但是您可以通过诸如 POST 所有请求标头中的特殊键标头中的 30 分钟更改令牌由客户端 IP 限制的服务器端 API 如果搜索API的安全性真的很重要,通过登录进行验证;如果没有,那就放手吧,因为它不在您的关键路径中。让我们专注于其他重要的事情。

【讨论】:

感谢您的回复。我想我会按照你说的去做,专注于其他事情。但我会看看我是否可以在标题中实现关键更改,使其他人更难使用。我试图保护它的主要原因是因为后端的某些功能确实调用了具有请求限制的服务。所以我想让其他人尽可能难以达到我的极限 当然,您可以尝试一些中间件/框架来限制请求。 已经应用了节流阀!我想我可能只是有点偏执,这是一回事吗? :D 如果有的话,什么是“最佳”方式。处理标题键? 我以前和你一样。我理解你。但现在,我会让事实驱使我去处理事情。我建议你专注于处理其他重要的功能需求,而不是那些不会阻碍你前进的非功能需求。【参考方案2】:

我在同一条“船上”,我当前的设置实际上是在 VueJs 中,但在来到 *** 之前,我开发了一种方法,前端调用服务器,然后服务器调用 API,所以在浏览器中,您只会看到对服务器层的调用,唯一的限制是调用必须来自相同的主机名。

后端由 expressJs 处理,前端由 VueJs 处理

// protect /api calls to only be originated from 'process.env.API_ALLOW_HOST'
app.use(api.allowOnlySameDomainRequests());

...

const allowHostname = process.env.API_ALLOW_HOST ||'localhost';

exports.api = 
    ...
    allowOnlySameDomainRequests: (req, res, next) => 
        if(req.url.startsWith('/api') && req.hostname === allowHostname) 
            // an /api call, only if request is the same
            return next();
         else if (!req.url.startsWith('/api')) 
            // not an /api call
            return next();
        

        return res.redirect('/error?code=401');
    ,
    ...
;

在我们的例子中,我们使用 Oauth2(Google 通过 passportJs 签名)来登录用户,我总是有一个由 OAuth2 成功重定向给出的用户 ID,并且该用户 ID 在标头中一起传递给 API使用 apikey... 在服务器中,我检查该用户 ID 权限并允许或不允许执行该操作。

但即使是我也试图找到更好的东西。我见过几个 javascript 前端应用程序使用对其后端的调用,但它们使用 Bearer 令牌。

作为一个好奇的用户,你会看到所有 API 的路径以及它们是如何组成的,但在我的例子中,你只看到对 expressJs 后端的调用,并且只有在那里我才会转发到真正的 API……我不知道这是否只是“更多工作”,但以这种方式解决问题似乎更“安全”。

【讨论】:

以上是关于处理来自前端的 API 调用的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

Vue:处理多个 API 调用的最佳实践

Spring boot REST API 仅接受来自 Angular 前端的调用

最佳后台处理/API 调用方法?

在javascript和axios中为来自前端的每个api调用发送firebase身份验证令牌

Nuxt.js - API 调用的最佳场所

Express 和 Nodejs:调用外部 API 的最佳方式