SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|

2023-08-21(Mon) MaveでOAuth2.0認証でGmailをPOP/SMTPする

  リフレッシュ機能を、前回作ったoauth2.rbに加える。

 *** 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

  そして、Maveへの修正は恐ろしいほどに小規模だった。ほぼconfigだけで済んだようなものだ。

 #---------------------------------------------------------------
 #
 #   メールアカウント「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されるので問題ないし。

  あ、net/popライブラリへのOAuth2.0認証機能の追加は、後方互換のため、パラメータを増やすのでなく、既存のapopを指定するパラメータに押し込む形に変更した。

      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

  つうわけで、最初はダメモトで「OAuth2.0」を学んでみるか、くらいのつもりだったが、ほぼ実用に足る形で実装が完了してしまった。実に気分がいいなぁ。たぶん使わないんだけど。

  つうわけで、リポジトリにコミットして完了である。