使用oauth2+django获取授权toAccess用户的gmail

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

I正在使用本教程:https://www.geeksforgeeks.org/python-django-google-google-authentication-andertication-and-fetching-mails-from-scratch/。但是,oauth2client库已弃用,近9年来一直没有触及。我已经寻找了各种教程,但它们似乎是由AI撰写的。它们没有意义,并做一些事情,例如告诉您在不使用凭据的代码中包含凭证。

我的问题是,如何将OAuth2实现到我的Django应用程序中,以便用户可以访问Django网站并允许阅读他们的电子邮件?

django oauth-2.0 google-oauth django-allauth
1个回答
0
投票
I将从一开始就开始,并在不使用

oauth2

库的情况下描述一个最小工作的示例。为简单起见,本教程故意省略了错误处理和安全工作。您可能需要尝试使用
django-allauth
,以实现
google oauth2
身份验证,查看Documentation
。另外,我建议您阅读this文档,thisthis,并进行所有设置(如果您还没有设置)。 要工作,我们需要一些高级Python库来提出http请求,例如:request

httpx

。在此示例中,我将使用
httpx
。此外,由于我们将在测试模式下使用
gmail.api
Test users
,因此您需要添加
gmail
#  views.py
from typing import Self, Sequence  
from urllib.parse import urlencode  
  
import httpx  
  
from django.http import HttpResponseRedirect, JsonResponse  
from django.shortcuts import render  
  
GOOGLE_OAUTH2_CREDENTIALS = {  
    'client_id': 'your_client_id',  
    'client_secret': 'your_client_secret',  
    'scope': 'profile email https://mail.google.com/'.split(),  
    'redirect_uri': 'your_redirect_uri',  
}  
  
  
class GoogleOauthBackend:  
    AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth'  
    ACCESS_TOKEN_URL = 'https://oauth2.googleapis.com/token'  
    USER_INFO_URL = 'https://www.googleapis.com/oauth2/v2/userinfo'  

    def __init__(  
            self,  
            client_id: str,  
            client_secret: str,  
            scope: Sequence[str],  
            redirect_uri: str,  
            **optional) -> None:  

        self.client_id = client_id  
        self.client_secret = client_secret  
        self.scope = scope  
        self.redirect_uri = redirect_uri  
        self.optional = optional  

    @classmethod  
    def from_credentials(cls, credentials: dict) -> Self:  
        return cls(  
            client_id=credentials['client_id'],  
            client_secret=credentials['client_secret'],  
            scope=credentials['scope'],  
            redirect_uri=credentials['redirect_uri'],  
        )  

    def get_auth_url(self) -> str:  
        params = {  
            'client_id': self.client_id,  
            'redirect_uri': self.redirect_uri,  
            'response_type': 'code',  
            'scope': ' '.join(self.scope),  
            **self.optional,  
        }  
        return f'{self.AUTH_URL}?{urlencode(params)}'  

    def get_user_info(self, access_token: str, token_type: str) -> dict:  
        response = httpx.get(  
            url=self.USER_INFO_URL,  
            headers={  
                'Authorization': f'{token_type} {access_token}',  
            },  
        )  
        return response.json()  

    def get_access_token(self, code: str) -> tuple[str, str]:  
        params = {  
            'client_id': self.client_id,  
            'client_secret': self.client_secret,  
            'code': code,  
            'redirect_uri': self.redirect_uri,  
            'grant_type': 'authorization_code',  
        }  
        response = httpx.post(url=self.ACCESS_TOKEN_URL, data=params)  
        data = response.json()  
        return data['access_token'], data['token_type']  


class GoogleGmailClient:  
    API_URL = 'https://gmail.googleapis.com'  

    def __init__(self, user_id: int, access_token: str, token_type: str):  
        self.user_id = user_id  
        self.access_token = access_token  
        self.token_type = token_type  

    def get_user_mail_messages(self):
        url = f'{self.API_URL}/gmail/v1/users/{self.user_id}/messages'  
        return httpx.get(url=url, headers=self.headers).json()['messages']  

    def get_user_mail_message_details(self, mail_id: str):
        url = f'{self.API_URL}/gmail/v1/users/{self.user_id}/messages/{mail_id}'  
        return httpx.get(url=url, headers=self.headers).json()  

    @property  
    def headers(self):  
        return {  
            'Authorization': f'{self.token_type} {self.access_token}',  
        }  


def main_page(request):  
    return render(request=request, template_name='main_page.html')  


def google_login(request):  
    google_oauth_backend = GoogleOauthBackend.from_credentials(  
        credentials=GOOGLE_OAUTH2_CREDENTIALS,  
    )  
    return HttpResponseRedirect(google_oauth_backend.get_auth_url())  


def google_callback(request):  
    code = request.GET.get('code')  
    google_oauth_backend = GoogleOauthBackend.from_credentials(  
        credentials=GOOGLE_OAUTH2_CREDENTIALS,  
    )
    access_token, token_type = google_oauth_backend.get_access_token(code=code)  
    user_info = google_oauth_backend.get_user_info(  
        access_token=access_token,  
        token_type=token_type,  
    )  
    user_id = user_info['id']  
    first_user_mail_details = get_user_first_mail_message_details(
        GoogleGmailClient(  
            user_id=user_id,  
            access_token=access_token,  
            token_type=token_type,  
        ),  
    )  
    return JsonResponse(data=first_user_mail_details)  


def get_user_first_mail_message_details(gmail_client: GoogleGmailClient):
    mails = gmail_client.get_user_mail_messages()
    first_mail_id = mails[0]['id']  
    return gmail_client.get_user_mail_message_details(mail_id=first_mail_id)
here
,您的{#main_page.html#} <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form method="POST" action="{% url 'google_login' %}"> {% csrf_token %} <button type="submit">GOOGLE</button> </form> </body> </html> 帐户会做。
这里是使事情正常工作的最小工作示例:

# urls.py from django.urls import path from . import views urlpatterns = [ path('', views.main_page), path('google-login/', views.google_login, name='google_login'), path('google-callback/', views.google_callback), ]

HTML
GOOGLE
本质上,此示例有三个终点。主页加载
google-login/
,带有一个

google-callback/

按钮,单击按钮将调用
code
端点,该端点将重定向用户通过Google登录。之后,Google将调用
api
端点,如果一切顺利,您将收到the the the the to and to and to and for访问访问令牌,这将允许您代表用户代表用户提出认证的请求。
加法,这里有一些有用的链接:

您可以请求的gmail示波器。
GMAILAPI端点
.
在Gmail

API端点上,是更详细的文档。

准备了不同的编程语言,尤其是Python。

这是一个例子,不是为了生产,正如我上面写的那样,许多事情都非常简化,但是它应该为您提供一些见识和许多链接,包括现成的解决方案。我希望这对您有帮助。
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.