如何在Django≥2.0环境下不使用oaut2client存储Google凭证到Django模型
无oaut2client依赖的Google凭证Django存储实现
核心逻辑
oaut2client自带的DjangoORMStorage本质仅做三件事:按指定字段匹配模型实例、将Credentials对象序列化后存入对应字段、从字段读取字符串反序列化为Credentials对象,完全可以自行实现这套逻辑,无版本兼容障碍。
具体实现步骤
1. 调整适配Django模型
模型结构与旧版实现保持一致,仅需将存凭证的字段设为TextField,可完整容纳序列化后的JSON格式凭证内容:
# models.py from django.db import models from django.contrib.auth import get_user_model User = get_user_model() class GoogleCred(models.Model): # 对应旧版Storage的匹配字段act,可根据实际业务替换为任意关联实体 act = models.ForeignKey(User, on_delete=models.CASCADE, related_name="google_cred") # 存储序列化后的凭证字符串 credential = models.TextField(blank=True, null=True)
2. 实现自定义读写逻辑
依赖Google官方当前维护的认证组件google-auth-oauthlib,实现和旧版Storage完全对齐的读写能力:
- 凭证写入:
from google.oauth2.credentials import Credentials from . import models def save_google_credential(act, credentials: Credentials): # 匹配对应当前act实体的凭证记录,无记录则自动创建 cred_record, _ = models.GoogleCred.objects.get_or_create(act=act) # 将Credentials对象序列化为字符串写入字段 cred_record.credential = credentials.to_json() cred_record.save()
- 凭证读取:
def load_google_credential(act): try: cred_record = models.GoogleCred.objects.get(act=act) if not cred_record.credential: return None # 从存储的字符串反序列化为可用的Credentials实例 return Credentials.from_json(cred_record.credential) except models.GoogleCred.DoesNotExist: return None
3. 替换旧版代码调用
原旧版代码片段:
storage = Storage(models.GoogleCred, 'act', act, 'credential') storage.put(credentials)
可直接替换为自定义方法调用,功能完全对齐:
save_google_credential(act, credentials)
注意事项
- 整套实现仅依赖Google官方长期维护的
google-auth-oauthlib组件,完全适配Django 2.0及以上所有版本,无废弃组件依赖问题 - 存量旧版存储的凭证可平滑迁移:读取旧版存储的序列化字符串后,通过
Credentials.from_authorized_user_info(json.loads(old_cred_str))即可完成格式适配,无需引导用户重新授权 - 如需实现凭证自动刷新,可在读取凭证后判断
credentials.expired状态,调用credentials.refresh(Request())完成刷新后,再次调用存储方法写回新的序列化内容即可,无需引入第三方存储组件
内容的提问来源于stack exchange,提问作者Sviat
相关产品推荐
相关产品推荐

