如何在 Django 中存储 Google Auth Credentials 对象?

问题描述 投票:0回答:2

我正在尝试将 Google 跟踪代码管理器集成到我的项目中。在官方文档中,Google 建议使用 oauth2client 库。不幸的是,这个库已被弃用。我使用了 google_auth_oauthlib。我可以获取令牌并使用此令牌向 Google 跟踪代码管理器 API 发送请求。但我不决定如何在 Django 中存储凭据对象。在 oauth2client lib 中,有用于模型的 CredentialsField。我们可以使用 DjangoORMStorage 在此字段中存储 Credentials 对象。但我无法使用这个已弃用的库。还有其他方法吗?

Google 跟踪代码管理器文档位于 此处

我的代码在这里:

from google_auth_oauthlib.flow import Flow
from googleapiclient.discovery import build

FLOW = Flow.from_client_secrets_file(
    settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON,
    scopes=[settings.GOOGLE_OAUTH2_SCOPE])

class GTMAuthenticateView(APIView):
    def get(self,request,**kwargs):
        FLOW.redirect_uri = settings.GOOGLE_OAUTH2_REDIRECT_URI
        authorization_url, state = FLOW.authorization_url(access_type='offline',
        include_granted_scopes='true')
        return Response({'authorization_url':authorization_url,'state':state})

    def post(self, request, **kwargs):
        FLOW.fetch_token(code=request.data['code'])
        credentials = FLOW.credentials
        return Response({'token':credentials.token})

class GTMContainerView(APIView):
    def get(self,request,**kwargs):
        service = get_service()
        containers = self.get_containers(service)
        return Response({'containers':str(containers),'credentials':str(FLOW.credentials)})

    @staticmethod
    def get_containers(service):
        account_list = service.accounts().list().execute()
        container_list = []
        for account in account_list['account']:
            containers = service.accounts().containers().list(parent=account["path"]).execute()
            for container in containers["container"]:
                container["usageContext"] = container["usageContext"][0].replace("['", "").replace("']", "")
                container_list.append(container)
        return container_list

def get_service():
    try:
        credentials = FLOW.credentials
        service = build('tagmanager', 'v2', credentials=credentials)
        return service
    except Exception as ex:
        print(ex)
django python-3.x google-tag-manager google-authentication oauth2client
2个回答
0
投票

我已经研究这个主题有一段时间了,但似乎没有任何现成的解决方案(除了旧的 oauth2client lib 中提供的解决方案)。几乎所有在线可用的文档都依赖于将凭据存储在磁盘存储上,这是我根本不喜欢的方法。所以基本上我最终创建了自己的模型,用于存储凭证对象中的相关信息,并使用一些辅助类方法来快速存储和从数据库中检索凭证。

我包含了相关代码,以防万一有人发现它有用。我用它来与 youtube api 交互,但授权部分没有注意到这一点:

#models.py
class GoogleCredential(models.Model):

    #In my case, I don't find necessary to store scopes in the DB
    #even though they are required information in the credentials object
    #So I just save it as a static var and inject it in the object
    #during the retrieval
    SCOPES = ["https://www.googleapis.com/auth/youtube", ]

    token = models.CharField(null=False)
    refresh_token = models.CharField(null=False)
    token_uri = models.CharField(null=False)
    client_id = models.CharField(null=False)
    client_secret = models.CharField(null=False)
    user = models.OneToOneField(User, null=False, on_delete=models.CASCADE)

    @classmethod
    def store_credentials(cls, credentials, user):
        credentials = GoogleCredential.objects.get_or_create(user=user)[0]
        credentials.token = credentials.token
        credentials.refresh_token = credentials.refresh_token
        credentials.token_uri = credentials.token_uri
        credentials.client_id = credentials.client_id
        credentials.client_secret = credentials.client_secret
        credentials.user = user
        credentials.save()
        return credentials

    @classmethod
    def get_credentials(cls, user):
        try:
            user_credentials = GoogleCredential.objects.get(user=user)
            credentials = Credentials(
                token=user_credentials.token,
                refresh_token=user_credentials.refresh_token,
                token_uri=user_credentials.token_uri,
                client_id=user_credentials.client_id,
                client_secret=user_credentials.client_secret,
                scopes=GoogleCredential.SCOPES
            )
        except Exception as ex:
            credentials = None
        return credentials

存储凭据的示例视图:

class YourAuthCallbackView(View):

    def get(self, request, *args, **kwargs):

        flow = Flow.from_client_secrets_file(
            get_secrets_file_path(),
            scopes=GoogleCredential.SCOPES,
            redirect_uri=request.build_absolute_uri('..')
        )
        path = request.get_full_path()
        flow.fetch_token(
            authorization_response=request.build_absolute_uri(path)
        )

        GoogleCredential.store_credentials(
            flow.credentials, 
            request.user
        )

        return redirect('/whatever')

在 api 请求中使用凭据的示例视图:

class YoutubeGetProfile(View):
    def get(self, request, *args, **kwargs):
        credentials = GoogleCredential.get_credentials(request.user)
        if credentials is not None:
            flow = Flow.from_client_secrets_file(
                get_secrets_file_path(),
                scopes=GoogleCredential.SCOPES,
                redirect_uri=request.build_absolute_uri('...')
            )
            youtube_api = build('youtube', 'v3', credentials=credentials)
            request = youtube_api.channels().list(part='snippet,contentDetails,statistics', mine=True)
            response = request.execute()
            #...
    return redirect('/whatever')

-1
投票

只需切换到 Django 2 pip 安装 Django==2.2.12 我做到了并且效果很好

© www.soinside.com 2019 - 2024. All rights reserved.