簡體   English   中英

如何使用 tls/ssl 將 SMTP email 發送到 office365 和 python

[英]How to send SMTP email for office365 with python using tls/ssl

我正在嘗試使用 python 從我的 office365 公司帳戶發送 email。我是 python 的新手。此代碼以前在使用我的 hotmail 帳戶時有效,但是現在我需要發送機密信息,我必須使用我的公司 email。

我嘗試了幾件事。

  • 驗證我的用戶名和密碼是正確的。
  • 同時使用了 python2 和 python3。 兩者都給出相同的錯誤: 535 5.7.3 Authentication unsuccessful
  • 當我遇到上述錯誤時,我以前使用的是mailserver.starttls() ,然后經過一些研究,我試圖通過一個
    證書。 mailserver.starttls(certfile='office365.cer')

我不清楚證書部分,但我的步驟包括,在線查找如何導出證書。 使用chrome瀏覽器, microsoftonline.com有鏈證書。 我可以導出根和根下面的級別,但不能導出最后一個級別。 我不知道如何傳遞這兩個文件,所以我只是傳遞了根證書。 此時我收到錯誤: ssl.SSLError: [SSL] PEM lib (_ssl.c:3309)

我被困在這一點上。 任何幫助表示贊賞。 下面使用的代碼

import smtplib

mailserver = smtplib.SMTP('smtp.office365.com',587)
mailserver.ehlo()
mailserver.starttls(certfile='office365.cer')
mailserver.ehlo()
mailserver.login('user@company.co', 'password')
mailserver.sendmail('user@company.co','user@company.co','python email')
mailserver.quit()

嗯,你快到了。 以下代碼可以解決問題:

import smtplib

mailserver = smtplib.SMTP('smtp.office365.com',587)
mailserver.ehlo()
mailserver.starttls()
mailserver.login('user@company.co', 'password')
#Adding a newline before the body text fixes the missing message body
mailserver.sendmail('user@company.co','user@company.co','\npython email')
mailserver.quit()

使用以下鏈接了解更多信息:

http://www.aventistech.com/2016/03/07/python-send-email-via-office-365-tls/

https://docs.python.org/3/library/smtplib.html

https://gist.github.com/jasonjoh/3ec367594c3fa662ee983a617bdc7deb

我找到了一個對我有用的庫:

https://github.com/O365/python-o365

https://pypi.python.org/pypi/O365

使用 PIP 安裝它,然后:

from O365 import Message
o365_auth = ('YourAccount@office365.com','YourPassword')
m = Message(auth=o365_auth)
m.setRecipients('reciving@office365.com')
m.setSubject('I made an email script.')
m.setBody('Talk to the computer, cause the human does not want to hear it any more.')
m.sendMessage()

對我來說,@Prometheus 提供的答案是“RuntimeError:未找到身份驗證令牌。需要身份驗證流程”,如評論所述。 這可能是因為我的公司 email 啟用了 2fa。 所以我必須按照https://github.com/janscas/pyo365#authenticationhttps://pypi.org/project/O365/#authentication中提供的步驟進行操作

要使用 oauth,您首先需要在 Microsoft 應用程序注冊門戶中注冊您的應用程序。

  1. 登錄Microsoft 應用程序注冊門戶
  2. 創建一個應用程序,記下您的應用程序 ID (client_id)
  3. 在“應用程序機密”部分下生成新密碼(client_secret) 在“平台”部分下,添加新的 Web 平台並設置https://login.microsoftonline.com/common/oauth2/nativeclient”作為重定向 URL
  4. 轉到 API 權限 > 添加權限 > Microsoft Graph > 委派權限,添加以下權限:
    • IMAP.AccessAsUser.All

    • 郵件.發送

    • POP.AccessAsUser.All

    • 用戶.讀取

    • SMTP.發送

    • offline_access # 如果你希望刷新令牌在 o365_token.txt 中可用。 否則,您需要每 1 小時獲取一次訪問令牌。 在此處輸入圖像描述

  5. 運行以下 python 腳本獲取訪問令牌,該令牌將存儲在當前目錄中名為 o365_token.txt 的文件中
from O365 import Account

scopes =  ["IMAP.AccessAsUser.All", "POP.AccessAsUser.All", "SMTP.Send", "Mail.Send", "offline_access"]

account = Account(credentials=('client_id_of_azureapp', 'client_secret_of_azureapp'))
result = account.authenticate(scopes=scopes)  # request a token for this scopes
  1. 通過提供上一步生成的 authtoken 文件,使用以下腳本發送 email。
from O365 import Account
from O365.utils.token import FileSystemTokenBackend
tk = FileSystemTokenBackend(token_path=".", token_filename="o365_token.txt")

credentials = ('client_id', 'client_secret')

account = Account(credentials, auth_flow_type = 'public',token_backend=tk)
m = account.new_message()
m.to.add('user@company.com')
m.subject = 'Testing!'
m.body = "George Best quote: I've stopped drinking, but only while I'm asleep."
m.send()

注意:如果您有管理員同意或者您是管理員或 azure 帳戶,您可以跳過步驟 4、5、6 並直接使用以下代碼。

from O365 import Account
from O365.utils.token import FileSystemTokenBackend
tk = FileSystemTokenBackend(token_path=".", token_filename="o365_token.txt")

credentials = ('client_id', 'client_secret') # from step 2,3
account = Account(credentials, auth_flow_type = 'credentials', tenant_id="your_app_tenant_id") # tenant_id (required) available just below client_id in azure

if account.authenticate():
    print('Authenticated!')

mailbox = account.mailbox("user@company.com") # Your email (required) from which you want to send email (your app should have permission to this email)
m = mailbox.new_message()
m.to.add('touser@company.com')
m.subject = 'Testing!'
m.body = "George Best quote: I've stopped drinking, but only while I'm asleep."
m.send()

最有可能的問題不在於您的代碼,而在於 Exchange Online 配置。

我敢打賭535 5.7.3 Authentication unsuccessful被拋出,因為經過身份驗證的 SMTP(SMTP AUTH 協議)在您的 Exchange Online 組織中被禁用。

在這里您可以找到我的回答,解釋如何為您發送電子郵件的用戶啟用 SMTP AUTH。 您必須是 Office 365 組織管理員才能執行此操作,或者您可以向您的管理員尋求幫助。

之后mailserver.starttls()應該可以工作了。 請注意,您不需要在該調用中指定證書。

代碼略有改動。 上面的代碼不起作用。 請使用以下代碼。 參考

from O365 import Account

credentials = ('client_id', 'client_secret')

account = Account(credentials)
m = account.new_message()
m.to.add('to_example@example.com')
m.subject = 'Testing!'
m.body = "George Best quote: I've stopped drinking, but only while I'm asleep."
m.send()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM