如何实现Python REST身份验证

2 投票
3 回答
984 浏览
提问于 2025-04-17 18:08

我还是个新手,想做以下事情:

我有一些服务接口,比如:

@login_required
@app.route('/')
def home():
  pass

@login_required
@app.route('/add')
def add():
  pass

@login_required
@app.route('/save')
def save():
  pass

@login_required
@app.route('/delete')
def delete():
  pass
  • 我希望用户在调用这些接口时能够进行身份验证。
    问题
  • 我该如何用Python来验证REST调用?
  • 我怎么确保当调用执行任何接口时,它们都是经过身份验证的?
  • 我基本上想在HTTP头部进行所有的身份验证,而不保存任何状态,这样将来可以更好地扩展(就像亚马逊S3那样),也就是说,任何调用可能会去不同的服务器,但仍然能够进行身份验证。

我对REST的世界完全陌生,不知道该怎么做。

谢谢

3 个回答

0

看你的API,感觉它不是很符合RESTful的标准。URI(统一资源标识符)应该代表某个具体的实体,而不是动作。比如说,如果你在处理用户这个实体,你可以用你的域名加上/user,比如你的域名是yourdomain.com,那么就可以用这个地址来进行各种操作,比如创建、删除、更新和获取用户信息,这些操作可以通过HTTP的不同方法来实现,比如POST、DELETE、PATCH和GET(如果你用的是Flask框架,这些操作都很简单)。

在安全性方面,我想有很多种方案,但我用过的一种是通过一个初始的身份验证请求来生成一个会话令牌,这个令牌是根据一个密钥和一个秘密生成的。我建议你找一些专门的在线资源,了解如何生成密钥和秘密对,以及如何生成会话令牌。

关于扩展性,我猜你的担心是会话不应该只局限于某一台机器。身份验证的数据可以存储在一个和HTTP前端分开的地方。这样的话,你就可以增加更多的web服务器来扩展你的前端,或者根据需要增加更多的数据存储。

1

安全问题可不是小白能随便搞定的。最好使用一个成熟的框架,依赖它的实现。多看看源代码,读读相关的博客和论文,慢慢地你就能设计自己的系统了。

在这个过程中,可能会出现很多问题,一旦你部署了某个协议,可能就无法再改回来了,这样会影响到已经在使用的客户端。

通常,验证请求的方式是使用两个令牌,通常叫做公钥和私钥(秘密密钥)。还有一种变体是用私钥生成一个短期的会话令牌。另一种变体是为每个客户端使用特定的API密钥。无论如何,这个令牌通常会放在HTTP头部(可以是标准的cookie或者自定义的),也可以放在请求体里。一般来说,它们不会附加在URL上,因为秘密信息可能会被记录到日志文件里。此外,你还需要注意如何以及在哪里存储这个秘密密钥。

根据你使用的通道(比如普通的HTTP),你可能想用HMAC来签名请求,而不是把秘密信息暴露出去。你还得防范重放攻击。时间攻击也是有可能的。加密碰撞可能会破坏你的方案。你可能需要令牌来防止CSRF(如果不涉及网页浏览器,这个其实不太需要,但你没有说明这一点)。

再说一遍,选择一个框架,不要自己随便编写代码。坏的软件通常可以修复,但安全漏洞可能会造成真正的损失。

2

首先,有个问题,你是在验证用户、客户端,还是两者都要验证呢?

如果是验证客户端的话,我推荐使用HTTP MAC认证,这适合用在REST服务的身份验证上。你可以看看Mozilla的服务macauthlib,以及它是如何在他们的pyramid_macauth项目中使用的。通过这个pyramid_macauth的例子,你应该能学到如何用macauthlib来保护你的服务。另外,搜索一下是否有人在Flask中尝试过这个也是个好主意。

如果是要同时验证用户和客户端,或许可以看看OAuth 2.0的相关内容(HTTP MAC认证是一个相关的规范)。

我本来想分享更多链接的,不过这是我第一次发帖,似乎需要先积累一些经验才能分享更多链接。:)

撰写回答