自定义REST服务的API身份验证最佳实践
我会尽可能地保持这个框架的独立性,但我会参考我个人使用的框架来提供一些上下文。还有,对不起,这是一个很长的问题 上下文:我正在一个在线平台上工作。它由两个不同的服务器组成,一个“后端”提供公共REST(ish)API(在,比方说API.example.com),另一个“前端”使用Sapper(Svelte)和ssr(example.com)。后者基本上服务于API客户机 显然,某些端点与特定帐户相关,因此需要身份验证。据我所知,这有两种不同的方法,它们有不同的漏洞:自定义REST服务的API身份验证最佳实践,api,security,authentication,xss,csrf,Api,Security,Authentication,Xss,Csrf,我会尽可能地保持这个框架的独立性,但我会参考我个人使用的框架来提供一些上下文。还有,对不起,这是一个很长的问题 上下文:我正在一个在线平台上工作。它由两个不同的服务器组成,一个“后端”提供公共REST(ish)API(在,比方说API.example.com),另一个“前端”使用Sapper(Svelte)和ssr(example.com)。后者基本上服务于API客户机 显然,某些端点与特定帐户相关,因此需要身份验证。据我所知,这有两种不同的方法,它们有不同的漏洞: 会话身份验证(cookie
- 会话身份验证(cookie),易受CSRF攻击
- 令牌身份验证(标头),易受XSS攻击(通常令牌保存在
中)localStorage
localStorage
感到非常焦虑,我明白了,因为攻击者可以使用XSS窃取令牌并模拟用户。因此:
- 将令牌存储在httpOnly cookie中
- 每个请求都会转到example.com/api/[…]
- 这些端点充当“代理”,从cookie中获取令牌并将其放入授权标头中,以将请求转发到API.example.com上的实际API
localStorage
方法,但没有实际使用localStorage
,以便利用ssr。我可以使用Sapper中间件读取cookie并将令牌存储在Sapper会话中:
sapper.middleware({
会话:(请求、恢复)=>({
授权:getCookie(req,'supersecret')//从请求中获取supersecret cookie
})
})
对于那些不了解Sapper的人来说,session
在此上下文中基本上是一段由服务器初始化并与客户端共享的内存。使cookie httpOnly真正起不到作用,因为JS仍然可以使用会话存储访问该值。但是,由于服务器现在可以在页面重新加载期间访问令牌,我们现在可以利用ssr(在服务器上呈现从API获得的私有信息有多有用是有争议的,但为什么不呢?)
问题是:这显然不是一种标准方法,因此我不理解它可能导致(或已经造成)的问题,因为我似乎找不到任何不利之处。我在想什么/做错了什么?这真的可以吗
p.S.:如果我想使用API密钥并限制API使用,“前端代理”是强制性的,但我认为我并不真的需要它(如果我错了,请纠正我)如果有疑问,请查看专家如何处理该问题(除非您的方法新颖)。例如,银行的安全性很高,会话寿命很短,因此用户必须每x秒重新登录一次,因此即使攻击者窃取了第一个会话密钥,在您重新验证后,他也不会拥有新会话(假设他没有窃取新会话密钥的有争议的方法)它增加了一个障碍,但不是最终的防御,因为这并不存在。 也许你还可以看看使用私钥和公钥对的非对称加密,或者独特的代码生成器,前端必须始终根据前端和后端都拥有的加密密钥生成新的密码短语,并且你必须在每个请求中发送每一个不断演变的密码,攻击者将无法通过此安全措施,除非他能够访问前端代码,这同样不是终极防御,而是攻击者的额外障碍。一种更奇特的方法是使用机器学习来识别典型的用户行为模式,并标记出普通活动,如果当前活动会话中的置信度较低,则发送警报/重新验证。本地存储(或MemoryStorage,如果您愿意)对于产品而言永远不是一个好的解决方案。如果您只是在做一个演示或展示一个更改,那么您应该坚持使用本地存储内存缓存。将Redis用于专用缓存服务 这取决于您是否希望使用基于令牌的系统或基于会话的系统来确保服务器和客户端之间的一致性。您可以在请求中输入特定参数,以确保更好的身份(I.P.位置、更短的到期时间等)
设置https证书以使XSS攻击的效果降低。利用服务器生成的令牌确保基于会话的CSRF攻击更难执行(生成的令牌可以是非对称或对称类型)。因此,您真正想做的是: