You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中安全存储OAuth2访问令牌与刷新令牌

我来分享几个Django社区里常用的、经过实践验证的安全存储OAuth令牌的方案,正好匹配你用Azure AD + Microsoft Graph API的场景:

1. 使用加密字段存储令牌

最直接的方式是把令牌字段加密后存入数据库,确保即使数据库被非法访问,令牌也无法被直接使用。

  • 推荐使用django-encrypted-fields第三方包,它基于cryptography库实现了字段级加密,配置简单:
    • 安装包:pip install django-encrypted-fields
    • 在settings.py的INSTALLED_APPS里添加encrypted_fields
    • 生成加密密钥:运行from cryptography.fernet import Fernet; print(Fernet.generate_key())得到密钥,千万不要硬编码在代码里,把它存在环境变量中(比如用python-dotenv加载.env文件)
    • 在模型中定义加密字段:
      from django.db import models
      from encrypted_fields.fields import EncryptedCharField
      
      class UserOAuthToken(models.Model):
          user = models.OneToOneField(User, on_delete=models.CASCADE)
          access_token = EncryptedCharField(max_length=2048)
          refresh_token = EncryptedCharField(max_length=2048)
          expires_at = models.DateTimeField()
      
  • 如果你想更灵活,也可以自定义加密字段:继承models.Field,在to_python和get_prep_value方法里用Fernet做加密解密,核心逻辑和上面类似,只是需要自己实现字段类。
2. 加密密钥的安全管理

密钥是加密的核心,一定要做好防护:

  • 绝对不要把密钥硬编码到代码或配置文件里,生产环境优先用Azure Key Vault存储密钥,然后通过Azure SDK让Django应用动态获取密钥;如果是测试环境,可以用python-dotenv把密钥存在.env文件中,并且确保.env不会被提交到版本控制。
  • 密钥要定期轮换,轮换时注意更新所有依赖该密钥的加密数据(或者用密钥版本管理,比如Azure Key Vault的版本功能)。
3. 令牌权限与生命周期的安全优化

除了加密存储,还要从令牌本身减少风险:

  • 最小权限原则:在Azure AD应用注册时,只请求你的定时任务需要的Microsoft Graph权限(比如Mail.Read),不要请求不必要的权限,就算令牌泄露,危害范围也会很小。
  • 定期更新令牌:利用刷新令牌定期获取新的访问令牌,更新数据库中的access_token和expires_at字段,旧的访问令牌过期后就失去效用了。
  • 避免存储不必要的令牌:如果访问令牌有效期足够短,你可以只存储刷新令牌,每次需要调用API时再用刷新令牌获取新的访问令牌,减少敏感数据的存储时间。
4. 数据库与服务器的额外安全防护
  • 数据库层面:开启透明数据加密(比如Azure SQL的TDE),同时严格控制数据库的访问权限,只有应用服务器能访问数据库,禁止外部直接连接。
  • 应用服务器层面:开启HTTPS,限制服务器的入站流量,定期更新系统和依赖包,避免服务器被入侵导致密钥或令牌泄露。

另外,如果你的项目已经在用django-oauth-toolkit处理OAuth流程,你可以扩展它的令牌模型,把默认的明文字段替换成加密字段,或者自定义令牌存储后端来实现加密逻辑。

内容的提问来源于stack exchange,提问作者Aashay Amballi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 05:09:06