如何统一管理应用中第三方的 APIs?

2021-08-22 12:53:40 +08:00
 HarryYu

目前业务依赖大量的第三方 API,每个 API 都有自己的 authentication 的逻辑和相关 secrets ( client id,secrets 等等)。目前的做法是针对每个需要调用的应用都需要封装一层 API,然后将这些 secrets 用环境变量或者 config 来配置上去。

目前存在几个问题:

  1. 维护困难,一旦某个 secret 更新,需要挨个修改全部的应用,如果漏掉一个就会挂掉,部分应用需要紧急发布。
  2. 容易泄漏,这些 client secrets 比较重要,需要有权限控制。但是由于放在应用里面,任何一个应用开发者在本地启动的时候,都需要加载这些配置,一旦加载从内存等都是可以找到的。

目前的解决方案:

  1. 将这些 secrets 和逻辑收敛到一个 Web 应用中,这个应用将读取 secrets 然后支持接收请求,针对不同的第三方 API 进行对应的逻辑,比如获取 access token 然后附加到 request 上面转发给实际接口,然后返回接口的 response 。相当于透传请求,同时附加 access token 等信息。
  2. 这样只需要控制好这个应用的权限即可,维护 secrets 只需要修改一个地方。

但是这个解决方案的问题:

  1. 可能会形成单点故障,如果挂了的话。不过可以用 K8S 等方案解决。
  2. 请求本身来源的鉴权方式不好实现。由于可以被很多应用使用,这里假设最简单的情况就是没有任何校验,拿到任意请求均可透传。但问题很明显,一旦泄漏就完全没有秘密了。所以这个校验规则要如何实现? IP 白名单?还是再实现一套 OAuth 的校验?

所以目前的几个问题:

  1. 你的公司是否有类似需求?是如何实现的?
  2. 是否有开源或者 SaaS 服务提供类似的功能?这种技术或者需求是否有一个关键词?
  3. 数据库连接面临同样的需求,即避免将数据库用户密码等存放在各个应用中,数据库如何实现?
3371 次点击
所在节点    程序员
18 条回复
Sin
2021-08-22 13:01:39 +08:00
Secret Manager?
HarryYu
2021-08-22 13:32:12 +08:00
@Sin 谢谢回复。目前用的是 Azure key vault,但是还是会比较容易的泄漏,因为启动时应用还是需要拉下来全部的 secrets 。此外,其他应用也需要重复接入 key vault 的 SDK,然后 API wrapper 都要重复实现一遍。
Sin
2021-08-22 13:47:20 +08:00
@HarryYu 一般支持轮换和分角色单独鉴权的吧,感觉对于服务端应用安全性足够了
Azure 没用过,之前用 AWS 的时候单独写了个共用的配置库,现在用 Google Cloud Run 就直接映射到环境变量了,对应用透明用得还挺开心的
HarryYu
2021-08-22 13:55:13 +08:00
lu5je0
2021-08-22 13:56:26 +08:00
配置中心
HarryYu
2021-08-22 14:09:36 +08:00
@Sin 感谢补充。这里的问题其实不单单是配置如何管理自动映射,还有不暴露,而且要跨平台。比如我们的 use cases:

1. 使用 Postman 发请求查询第三方接口,绕开我们自己的逻辑进行测试。
2. 使用 serverless 的 function 做一些 jobs 和 checks
3. 一些 Web apps 在 K8S 里面

目前的 secrets 需要分别在三个地方设置使用。如果用 secret manager,由于 serverless 和 K8S 都是一家云服务提供商,可以通过接入 SDK 或者平台自动集成的方式映射。但是 Postman 没法接入,仍然需要获取所有 secrets 配置上去。

其次是安全问题,在开发中需要支持本地就可以跑起来,因此在本地也需要可以用 SDK 拉下来 secrets,然后每个开发者都会知道。

---

目前看了一圈,估计是要实现一个 internal 的 token 校验服务到这个 proxy server,然后一旦通过即可发送请求到第三方。大概架构图如下:

![]( https://blog.approov.io/hs-fs/hubfs/Using%20a%20Reverse%20Proxy%20to%20Protect%20Third%20Party%20APIs-2.png?width=1200&name=Using%20a%20Reverse%20Proxy%20to%20Protect%20Third%20Party%20APIs-2.png)

https://blog.approov.io/using-a-reverse-proxy-to-protect-third-party-apis
sy20030260
2021-08-22 14:36:13 +08:00
我们的大概思路差不多,所有调用三方接口的收敛到一个服务,对内网服务暴露 RPC 接口。鉴权的话根据业务情况判断是否需要,需要的话用现成的 RPC 鉴权方案,也不复杂
xwayway
2021-08-22 16:19:48 +08:00
如果出现大量的同一个 api 被不同服务引用的话。还是建议做一个单独的服务,来专门处理外部 api 调用的问题,内部通过 rpc 调用
Casbin
2021-08-22 16:24:04 +08:00
统一认证鉴权,可以采用我们社区开发的 Casdoor: https://v2ex.com/t/792573

除了管理 SSO 以及各种第三方 OAuth,Casdoor 其实也管理了所有的 OSS 存储、短信、Email 等的 client id, secret,并暴露出 API 供其他服务端调用,从而隐藏实现细节,例如调用 SendEmail 的 REST API 即可发送邮件
CDuXZMAPgHp1q9ew
2021-08-22 17:58:51 +08:00
富客户端?
HarryYu
2021-08-22 18:39:40 +08:00
@sy20030260 谢谢,看来可行,得自己搞一个了。
@xwayway 谢谢。
@Casbin 谢谢自荐,我去研究一下。
@wujichao 不是富客户端,是多种客户端调用。
jangit
2021-08-22 19:12:02 +08:00
最近有在做个可以来回切换 api 供应商的服务,算是包含楼主说的统一入口功能的,下个月写完丢 github 上
jeffreystoke
2021-08-22 20:54:34 +08:00
有同样的需求,我的解决方案是把单个 secret item 通过 fuse 挂载成一个独立文件,应用程序读取文件会触发授权请求,请求带有 uid, pid, 进程名以及进程调用链等,通过自定义 webhook 服务进行授权,成功授权才能读取文件内容。
Turkestan
2021-08-23 13:53:26 +08:00
上家也有这种需求,做法是写到 vscode 的配置文件里 (app-root-path/.vscode/secrets.json),至于内部怎么调用,还真没研究过
dany813
2021-08-23 14:43:25 +08:00
dany813
2021-08-23 14:43:50 +08:00
@dany813 那这样本地岂不是随便看了
egfegdfr
2021-08-23 16:49:45 +08:00
我们是两个账号、一个测试、一个正式、正式账号配置在配置中心、只有运维的人才能看到
付钱的第三方服务、都会免费给开测试账号的。
lowbug
2022-01-03 00:32:20 +08:00
@jangit 大佬搞完了吗,有同样需求,想学习下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/797284

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX