SVX日記
2023-08-21(Mon) MaveでOAuth2.0認証でGmailをPOP/SMTPする
アクセストークンでPOP/SMTPアクセスできたが、有効期限が1時間しかないので、そのためにリフレッシュトークンを使うのではないか? ということで、アレコレしてみたら、実際そうだった。
*** oauth2.rb.1st 2023-08-18 22:02:21.385069207 +0900
--- oauth2 2023-08-21 23:02:08.486091221 +0900
***************
*** 9,17 ****
if(ARGV.size == 0)
warn <<USAGE
Usage:
! $ ./oauth2.rb client_secret_xxxx.json > auth.html
$ google-chrome auth.html
! $ ./oauth2.rb client_secret_xxxx.json 'http://localhost/?code=xxxx'
USAGE
exit(1)
end
--- 9,18 ----
if(ARGV.size == 0)
warn <<USAGE
Usage:
! $ ./oauth2 client_secret_xxxx.json > auth.html
$ google-chrome auth.html
! $ ./oauth2 client_secret_xxxx.json 'http://localhost/?code=xxxx' > refresh_token.json
! $ ./oauth2 client_secret_xxxx.json refresh_token.json > access_token.json
USAGE
exit(1)
end
***************
*** 21,26 ****
--- 22,32 ----
cs = JSON.parse(fh.read)
}
end
+ rt = nil; if((it = ARGV[1]) =~ /^refresh/)
+ open(it) {|fh|
+ rt = JSON.parse(fh.read)
+ }
+ end
if(ARGV.size == 1 and cs)
auth_uri = 'https://accounts.google.com/o/oauth2/auth'
***************
*** 45,50 ****
--- 51,67 ----
}
auth_response = Net::HTTP.post_form(URI(auth_uri), auth_params)
puts(auth_response.body)
+
+ elsif(ARGV.size == 2 and cs and rt)
+ auth_uri = 'https://accounts.google.com/o/oauth2/token'
+ auth_params = {
+ client_id: cs['installed']['client_id'],
+ client_secret: cs['installed']['client_secret'],
+ refresh_token: rt['refresh_token'],
+ grant_type: 'refresh_token',
+ }
+ auth_response = Net::HTTP.post_form(URI(auth_uri), auth_params)
+ puts(auth_response.body)
else
warn('Invalid.')
$ ./oauth2 client_secret_xxxx.json refresh_token.json > access_token.json
#---------------------------------------------------------------
#
# メールアカウント「gmail」の設定
#
account = {}
account[:NAME] = 'Gmail' # アカウント名(必須)
account[:ENABLE] = false # 有効/無効(必須)
account[:USER_ADDRESS] = 'taro-yamada@gmail.com' # メールアドレス(必須)
account[:POP_SERVER] = 'pop.gmail.com' # メール受信(POP)サーバ
account[:POP_PORT] = 995
account[:POP_ACCOUNT] = 'taro-yamada' # 受信アカウント
account[:POP_PASSWORD] = 'Bearer ' + `./get_access_token access_token.json`.chomp
account[:POP_AUTHTYPE] = :oauth2
account[:POP_OVER_SSL] = true # SSL を使う
account[:POP_SSL_VERIFY] = OpenSSL::SSL::VERIFY_PEER # 証明書を検証する
account[:POP_SSL_CERTS] = '/etc/pki/tls/certs/ca-bundle.crt'
account[:SMTP_SERVER] = 'smtp.gmail.com' # メール送信(SMTP)サーバ
account[:SMTP_PORT] = 587 # 587(submission), 465(SMTP over SSL)
account[:SMTP_ACCOUNT] = account[:POP_ACCOUNT]
account[:SMTP_PASSWORD] = account[:POP_PASSWORD]
account[:SMTP_AUTHTYPE] = :oauth2
account[:SMTP_STARTTLS] = true # STARTTLS を使う
account[:SMTP_OVER_TLS] = false # TLS を使う
account[:SMTP_TLS_VERIFY] = OpenSSL::SSL::VERIFY_PEER # 証明書を検証する
account[:SMTP_TLS_CERTS] = '/etc/pki/tls/certs/ca-bundle.crt'
@configs[:ACCOUNTS] << account
# 定期的にアクセストークンをリフレッシュする必要がある
# ./oauth2 client_secret_xxxx.json refresh_token.json > access_token.json
config内にファイルから読む処理が入っているので、cron等でaccess_token.jsonを更新してもMaveの起動中は更新されず、再起動する必要があるが、再起動は瞬時にできるので特段の対策はなし。そもそも、Maverickとして使う場合はmave_fetchからpopされるので問題ないし。
def initialize(addr, port = nil, isapop = false)
@address = addr
@ssl_params = POP3.ssl_params
@port = port
@apop = isapop
+ if(isapop == :oauth2)
+ @apop = false
+ @oauth2 = true
+ end