リセットパスワードメールを送信[Django]


# SMTP


Simple Mail Transfer Protocol
smtpは、インターネット上で電子メールを送信するためのプロトコルであり、2つのメールサーバ間の通信をサポートする.

#gmail SMTPを使用するメールアカウントの送信を設定


## 1. IMAPの有効化


Gmailを他のEメールプラットフォームで検証を参照
設定>すべての設定の表示>転送とPOP/IMAPタブ

「変更を保存」(Save Changes)をクリックします.

こうしてIMAP를 사용할 수 있습니다.になりました.

## 2. ログインEメールクライアントの有効化



Gmailを他のEメールプラットフォームで検証
アプリケーションのパスワードを使用するか、セキュリティレベルの低いアプリケーションライセンスを設定するかにかかわらず、2022年5月30日からセキュリティレベルの低いアプリケーションライセンス設定は使用できなくなります.
したがって、レベル2の認証を使用します.

###第2段階検証



ただし、2レベルの認証を使用する場合は、後で設定します.pyのパスワードにアプリケーションパスワードを設定する
アプリケーションのパスワードは
[Gmail]レベル2の認証を使用する場合は、アプリケーションパスワードを生成して他のクライアント(セキュリティレベルの低いアプリケーション)に接続します。
に示すように、アプリケーションまたはデバイスにGoogleアカウントへのアクセス権を付与する16ビットのパスワードです.




生成時に表示される16ビットのアプリケーションパスワードを使用してメールサービスを行います.

###セキュリティレベルの低いアプリケーションへのアクセスを許可する(参照)


低レベルのアプリケーションへのアクセスを許可する方法でやりたいならGoole 계정관리

セキュリティレベルの低いアプリケーションへのアクセスを許可します.

#張高


##SMTP設定


Sending emailの私のように
django.core.メールを送信するSMTPをmailモジュールで設定する必要があります.

### settings.py


SMTP backend

を選択します.pyに電子メール転送を設定します.
EMAIL HOST PASWORDなど非表示の値をenvにインポートします.
# email
# 메일을 보내는 호스트 서버
EMAIL_HOST = 'smtp.gmail.com'

# ENAIL_HOST에 정의된 SMTP 서버가 사용하는 포트 (587: TLS/STARTTLS용 포트)
EMAIL_PORT = '587'

#  발신할 이메일 주소 '[email protected]'
EMAIL_HOST_USER = env('EMAIL_HOST_USER')

# 발신할 이메일 비밀번호 (2단계 인증일경우 앱 비밀번호)
EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD')

# TLS 보안 방법 (SMPT 서버와 통신할 떄 TLS (secure) connection 을 사용할지 말지 여부)
EMAIL_USE_TLS = True

# 사이트와 관련한 자동응답을 받을 이메일 주소
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

###Eメールの接続を確認するためのテスト


django.core.mail.send mail()を使用してメールを送信
>>> r = send_mail(subject='매일 제목', message='메일 내용', from_email='[email protected]', recipient_list=['[email protected]'])
>>> r
1
  • email from:メール送信アドレス
  • 受信者list:電子メールアドレスリスト
  • 1が戻ると、メールは正常に送信されます.

    ### urls.py


    Authentication Viewsドキュメント

    この文書では、ログイン、ログアウト、パスワード管理に関連する8つのビューとurlを提供し、最後の4つを使用してパスワードをリセットします.
    まず、urlとテンプレートを内蔵してから変更します.
    # urls.py
    
    from django.urls import includd
    ...
    
    urlpatterns = [
    	...
        path('password/', include('django.contrib.auth.urls')),
    ]
    

    パスワードリセットテスト

    password_reset/(http://localhost:8000/password/password_reset/接続)

    password reset linkのフォーム画面を電子メールで送信できます.password_reset_done/
    reset mypasswordボタンを押すと表示される画面password_reset_confirm/<uidb64>/<token>/
    ユーザーに送信されるリンクのタイプ

    非バージョン番号を変更するには、リンクをクリックします./reset/done/
    しかしDjango Administrationの画面をユーザーに見せることはできないので、別のカスタムテンプレートを作ります.

    ## url


    プロジェクト/urls。py

    from django.contrib import admin
    from django.contrib.auth import views as auth_views
    from django.urls import path
    
    
    urlpatterns = [
        ...
        path('password_reset/done/',
             auth_views.PasswordResetDoneView.as_view(template_name='account/password_reset_done.html'),
             name='password_reset_done'),
        path('reset/<uidb64>/<token>/',
             auth_views.PasswordResetConfirmView.as_view(template_name='account/password_reset_confirm.html'),
             name='password_reset_confirm'),
        path('reset/done/',
             auth_views.PasswordResetCompleteView.as_view(template_name='account/password_reset_complete.html'),
             name='password_reset_complete'),
    ]
    
    

    プロジェクト/アカウント/urls。py

    from django.urls import path
    
    from rest_framework_simplejwt.views import TokenRefreshView
    
    from . import views
    
    app_name = 'account'
    
    urlpatterns = [
        ...
        path('password_reset/', views.password_reset_request, name="password_reset"),
    ]
    

    ##テンプレートの設定


    プロジェクトフォルダの下にtemplatesフォルダを作成し、ここですべてのテンプレートファイルを管理します.
    このため、ライブラリがそのパス(templatesフォルダ)でテンプレートファイルを検索できるように設定します.pyのTEMPLATESのDIRSにos.path.join(BASE_DIR, 'templates')を追加する必要があります.
    # settings.py
    
    ...
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],  # <-이부분!
    ...

    以上のようにベースhtml, head.htmlは汎用です.
    パスワードリセット関連ファイルは、プロジェクト>テンプレート>アプリケーション名(Projects>Template>Application Name)に配置されています.

    base.html

    <!DOCTYPE html>
    <html lang="ko">
        {% include 'head.html' %}
        <body>
            {% block content %}
            {% endblock %}
        </body>
    </html>

    head.html

    <head>
        <meta charset="UTF-8">
        <title>Givwang</title>
    </head>
    

    ## password_reset



    password_reset.html

    {% extends 'base.html' %}
    
    {% block content %}
    
    	<!--Reset Password-->
    	<div>
      	 	<h2>비밀번호 재설정</h2>
    		<hr>
    		<p>비밀번호를 잊어버리셨나요?<br>
              가입하신 이메일을 입력해 주세요.<br>
              잠시 후 해당 이메일로 비밀번호 재설정 메일이 발송됩니다.</p>
            <form method="POST">
                {% csrf_token %}
                {{ password_reset_form }}
                <button type="submit">전송</button>
            </form>
      	</div>
    
    {% endblock %}

    ## password_reset_done



    password_reset_done.html

    {% extends 'base.html' %}
    
    {% block content %}
    
    	<!--Password reset sent-->
    	<div>
      		<h2>비밀번호 재설정 메일 발송 완료</h2>
    		<hr>
    		<p>
    			비밀번호 재설정을 위한 메일이 발송되었습니다.<br>
    			30분 내에 비밀번호를 재설정 해주세요.<br>
    			만약 메일이 오지 않는다면, 이메일 주소를 다시 한번 확인해 주시고, 스팸 폴더를 확인해 주세요.
    		</p>
      </div>
    
    {% endblock %}

    ##メールに送信されたテキスト



    プロジェクト/テンプレート/account/password reset email。txt

    {% autoescape off %}
    안녕하세요 :)
    
    다음 링크를 누르시면 [email protected] 계정의 기브왕 앱의 비밀번호를 재설정 할 수 있는 화면으로 이동합니다.
    
    {{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
    
    
    비밀번호 재설정을 요청하지 않았다면 이 이메일을 무시하셔도 됩니다.
    기브왕과 함께해주셔서 감사합니다.
    {% endautoescape %}
    電子メールで送信するコンテンツを含むtxtファイルを生成します.

    ## password_reset_confirm



    password_reset_confirm.html

    {% extends 'base.html' %}
    
    {% block content %}
    
      <!--Password Reset Confirm-->
        <div>
    	    <h2>비밀번호 재설정</h2>
    		<hr>
            <p>새 비밀번호를 입력해 주세요.</p>
            <form method="POST">
                {% csrf_token %}
                {{ form }}
                <button>저장</button>
            </form>
        </div>
    
    {% endblock %}
    ここまで問題なく、英語のように見えるので、韓国でサービスしている私のアプリは韓国語で展示すべきです.
    コンテンツをカスタマイズするために、オーバーラップする方法もあるかもしれませんが、まず設定します.pyにLANGUAGE_CODE = 'ko-KR'を追加し、サポート言語を韓国語にします.

    settings.py

    ...
    LANGUAGE_CODE = 'ko-KR'

    プラスするとハングルになります

    ## password_reset_complete



    password_reset_complete.html

    {% extends 'base.html' %}
    
    {% block content %}
    
        <div>
    	    <h2>패스워드 변경 완료</h2>
    		<hr>
            <p>패스워드 변경이 완료되었습니다. 기브왕 앱에서 다시 로그인 해주세요.</p>
        </div>
    
    {% endblock %}

    ## account/views.py

    from django.conf import settings
    from django.contrib.auth import get_user_model
    from django.contrib.auth.forms import PasswordResetForm
    from django.contrib.auth.tokens import default_token_generator
    from django.core.mail import send_mail, BadHeaderError
    from django.db.models.query_utils import Q
    from django.http import HttpResponse
    from django.shortcuts import render, redirect
    from django.template.loader import render_to_string
    from django.utils.encoding import force_bytes
    from django.utils.http import urlsafe_base64_encode
    
    
    
    def password_reset_request(request):
    	if request.method == "POST":
    		password_reset_form = PasswordResetForm(request.POST)
    		if password_reset_form.is_valid():
    			data = password_reset_form.cleaned_data['email']
    			associated_users = get_user_model().objects.filter(Q(email=data))
    			if associated_users.exists():
    				for user in associated_users:
    					subject = '[기브왕] 비밀번호 재설정'
    					email_template_name = "account/password_reset_email.txt"
    					c = {
    						"email": user.email,
    						# local: '127.0.0.1:8000', prod: 'givwang.herokuapp.com'
    						'domain': settings.HOSTNAME,
    						'site_name': 'givwang',
    						# MTE4
    						"uid": urlsafe_base64_encode(force_bytes(user.pk)),
    						"user": user,
    						# Return a token that can be used once to do a password reset for the given user.
    						'token': default_token_generator.make_token(user),
    						# local: http, prod: https
    						'protocol': settings.PROTOCOL,
    					}
    					email = render_to_string(email_template_name, c)
    					try:
    						send_mail(subject, email, '[email protected]' , [user.email], fail_silently=False)
    					except BadHeaderError:
    						return HttpResponse('Invalid header found.')
    					return redirect("/password_reset/done/")
    	password_reset_form = PasswordResetForm()
    	return render(
    		request=request,
    		template_name='account/password_reset.html',
    		context={'password_reset_form': password_reset_form}