{"id":19300791,"url":"https://github.com/takuya/ruby-google-xoauth2","last_synced_at":"2026-05-14T08:40:05.443Z","repository":{"id":261937896,"uuid":"852519699","full_name":"takuya/ruby-google-xoauth2","owner":"takuya","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-17T11:09:58.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-17T12:23:28.443Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/takuya.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-05T00:20:25.000Z","updated_at":"2025-02-17T11:10:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"a51f4556-4ea9-4f79-b3d1-212b8e49a361","html_url":"https://github.com/takuya/ruby-google-xoauth2","commit_stats":null,"previous_names":["takuya/ruby-google-xoauth2"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/takuya%2Fruby-google-xoauth2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/takuya%2Fruby-google-xoauth2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/takuya%2Fruby-google-xoauth2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/takuya%2Fruby-google-xoauth2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/takuya","download_url":"https://codeload.github.com/takuya/ruby-google-xoauth2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240402639,"owners_count":19795775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T23:15:50.065Z","updated_at":"2026-05-14T08:40:05.410Z","avatar_url":"https://github.com/takuya.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"## GMail にXOAUTH2でSMTP認証するサンプル\n\n## Installation\nAdd Following line into Gemfile.\n```ruby\ngem 'takuya-xoauth2', git: 'https://github.com/takuya/ruby-google-xoauth2.git'\n```\nbash by paste \n```sh\n## Gemfile\nURL=https://github.com/takuya/ruby-google-xoauth2.git\necho \"gem 'takuya-xoauth2', git: '$URL'\" \u003e\u003e Gemfile\n```\n## Usage Sample\n```ruby\n## require\nrequire 'takuya/xoauth2'\n## alias\nGMailXOAuth2 = Takuya::XOAuth2::GMailXOAuth2\n\n## env sample \nrequire 'dotenv/load'\nDotenv.load('.env', '.env.sample')\nclient_secret_path = ENV['client_secret_path'] # must\ntoken_path         = ENV['token_path'] # must\nuser_id            = ENV['user_id'] # option\n## select first of token.\nuser_id=YAML.load_file(ENV['token_path']).keys[0] if user_id.empty?\n\n## SMTP\nsmtp = GMailXOAuth2.smtp(client_secret_path, token_path, user_id)\nmail = Mail.new(\n  from: user_id, to: 'dummy', subject: 'Test', body: 'Hello.'\n)\nsmtp.sendmail(mail.encoded, user_id, mail.to)\n\n## IMAP \nimap = GMailXOAuth2.imap(client_secret_path, token_path, user_id)\nimap.select('INBOX')\nuids = imap.uid_search(['SUBJECT','Test', 'FROM', user_id])\n\n## POP3\npop3 = GMailXOAuth2.pop3(client_secret_path, token_path, user_id)\npop3.mails.empty?\n\n```\n### For develop.   \nsample for developer.\n```sh\n## clon project\nURL=git@github.com:takuya/ruby-google-xoauth2.git\ngit clone $URL\ncd ruby-google-xoauth2\n## in project\nbundle install\nbundle exec ruby bin/oauth-google-to-localhost.rb\nbundle exec rspec spec/\ngem build\n```\n\n## OAUTH2 トークンの発行\n\n```ruby\nbundle exec ruby bin/oauth-google-to-localhost.rb\n```\n\nENV設定してれば、Enter 連打。ブラウザは自分で開いて。\n\n## OAUTH2 クライアントの準備\n\n1. [GCP](https://console.cloud.google.com/) にアクセス、プロジェクトを作成\n1. プロジェクトの設定をする\n    - [Gmail API](https://console.cloud.google.com/apis/library/gmail.googleapis.com) をプロジェクトで有効に. \n    - その他、アプリに必要なAPIを有効にする。[People API](https://console.cloud.google.com/apis/library/people.googleapis.com),[Google Drive API](https://console.cloud.google.com/apis/library/drive.googleapis.com)など, \n1. [認証情報一覧](https://console.cloud.google.com/apis/credentials)に移動\n1. [認証情報（Credentials）を作成](https://console.cloud.google.com/apis/credentials/oauthclient) .\n1. 認証情報の詳細設定をする\n    - OAuth2 Client をWEBアプリで作成。\n    - 名前を決める\n    - コールバックアドレス`\"http://localhost:3304/oauth2callback\"`を入力して保存。\n    - JSON(client_secret.json)をダウンロード。\n    - secretが含まれてることを確認。\n\n\nメモ: APIではメアドやユーザ名が取得可能で動作チェックにも使えるので有効にしている。\nxoauth2単体ではPeopleは不要。GMail-APIにてメアドを取得可能なため、Peopleがなくてもメアドが取れる。\n\nメモ：コールバックのアドレスは自由に変えられる。状況に応じた変更後は、[詳細画面](https://console.cloud.google.com/apis/credentials/oauthclient)で変更後のコールバック・アドレスを追加する。\n\n\n## 注意事項\n\n- GCP が `testing(テスト)`だと 7日でREFRESH_TOKENが無効になる。\n- gSuite(google workspace) だと、半永久的REFRESH_TOKENになるはず\n- gsuite(google workspace)を持ってない場合、７日毎に再認証が必要\n\n\n\n## GMailとOAuthの認証とGoogle Workspaceについて\n\nGoogle Workspaceだと長過ぎるので以下では、GSuite（旧名）で呼称する。\n\n#### 独自メアドとGoogleアカウント\n\n- 独自ドメインのメアドでGoogleアカウントが作成可能である。\n- google workspace契約後は独自ドメインを設定する。\n\nこの２つの違いがある。独自ドメインのメアドは、Gsuiteとは限らない。\n\n独自ドメインのGoogleアカウントも存在しうる。\n\n\n#### OAuthのクライアント\n\nOAuthのクライアント（アプリ）には３種類がある\n\n|OAuth 同意画面設定|役割|\n|:-----|:-----|\n| INTERNAL | Gsuite(Google Workspace)内部ユーザー対象 |\n| EXTERNAL/Testing  | 一般Googlアカウント対象・試行用 |\n| EXTERNAL/published |一般Googlアカウント対象・本番用 |\n\n\n#### GoogleアカウントとGsuiteアカウント\nアカウントには大まかに３種類がある\n\n|アカウント|役割|管理者|\n|:-----|:-----|:-----|\n|GSuiteアカウント | 組織向けユーザー・アカウント| Gsuite契約者|\n|GSuiteサービスアカウント| 組織向けプログラム用アカウント |Gsuite契約者|\n|Googleアカウント | 一般アカウント(主に@gmail.com) |Google社|\n\n\nGoogleアカウントには独自ドメイン・メアドのGoogleアカウントも存在する。\n\nサービスアカウントはプログラムから使う用である。ドメイン全体のあれこれを行うために作る。\n\n#### InternalとExternal\n\nGsuiteでアプリを作るとInternal（内部）が選べる\n\n\n|アカウント| INTERNAL | EXTERNAL/Testing   | EXTERNAL/published |\n|:-----|:-----|:-------------------|:-----|\n|内部ユーザー      |無期限| ７日(外部扱い)               | 無期限(外部扱い) |\n|サービスアカウント |無期限| ７日(外部扱い)              | 無期限(外部扱い) |\n|外部ユーザ        | 不可 | ７日(外部扱い)              | 無期限 |\n\nGsuite以外（一般Googleアカウント）プロジェクトは、Externalのみ作成可能。\n\nGsuiteプロジェクトがExternal（外部）なら、一般Googleアカウントも対象にできる。\n\nGmailのtesting の場合、**7days** でトークンが無効化される。と一般的に言われている。\n\n[OAuth2 Auth](https://developers.google.com/identity/protocols/oauth2/scopes#oauth2)でログイン機能だけのスコープ指定（userinfo.email、userinfo.profile、openid）なら無制限、[Gmail-API](https://developers.google.com/gmail/api/auth/scopes#scopes)が含まれると７日である。\n\n#### SMTP認証方式とアカウント\n\nSMTPサーバーの認証方式とアカウント\n\n|認証方式 |役割|\n|:-----|:-----|\n| PASSWORD | ログイン・パスワード |\n| APP PASSWORD  | アプリ専用パスワード（2FA有効時) |\n| XOAUTH2 | OAUHT2トークンから作成 |\n| XOAUTH | OAUHT 1.0 トークンから作成 |\n\nXOAUTHはconsumer_secretを使う方法だが、今どきは使わない。\n\n`XOAUTH`と`XOAUTH2`は別物です。\n\n```ruby\n### 次は間違いがち\n## \":xoauth\", \":xoauth2\" の違いに注意。\nsmtp.start(server, user, token, :xoauth2)\nsmtp.start(server, user, token, :xoauth)\n```\n\n#### 認証方式とアカウント種別\n\n認証方式とGsuiteアカウント\n\n| 認証方式        |PASSWORD|APP PASSWORD| XOAUTH2|\n|:------------|:-----|:-----|:-----|\n| gsuiteアカウント | 可 | 利用可 | 利用可 |\n| Googleアカウント | 不可 | 利用可| 利用可（非実用的） | \n\nGoogleアカウントをXOAUTH2するには、「審査済」の公開アプリケーションが必要になる。iOSでメールアプリを作って公開して販売するような開発会社が使うのがXOAUTH＋Externalである、一般開発者がちょっと使うには無謀である。というか無益無能である。\n\nGsuiteアカウントは、アカウント管理責任が「契約者」にある。Googleは「GsuiteもOAUTH2に変えろと」脅してくるが、Google社の脅しは理解不能である。パスワード認証廃止かどうかは契約者が選ぶべきことである。繰り返すがパスワード管理責任者は「契約者」である。Gsuiteアカウントは`SMTPリレー`でメール配信可能なため、メアド≠ユーザであり、リレーのためにXOauth2するのはどうかと思う。\n\n\n#### GMailのメール配送手段\n\n|方式 |役割|\n|:-----|:-----|\n| GCP GMail API | API経由でメール送信 |\n| SMTP | ログインしてSMTPで配送 |\n| SMTP relay  | gserverへリレー配送する。 |\n\ngsuite契約者は、smtp-relay が使える。MTA-MTA転送が利用可能である。\n\n#### メール配送手法とアカウント種別\n\n| 種別/配送         | GMail API | SMTP | SMTP relay    |\n|:--------------|:-----|:-----|:--------------|\n| gsuite        |利用可 | 利用可| 利用可           |\n| gsuite legacy | 利用可 | 不可 | 不可(認証可能・配送不可） | \n| Googleアカウント   | 利用可| 不可 | 不可            | \n\nSMTP RelayはPostfixなどからGMailを通ってインターネットへグローバル配送する。MTA-MTA通信を通せる。\n\nリレー時はGsuite契約ドメインがenvelope fromであれば、fromメアドは何でも配送可能。つまりユーザー作成せずにメアドを使えるわけです。（良い抜け道かもしれない）\n１ユーザー契約あれば複数メアドから配送できる。受信メールはCatch-allなどすれば良いわけです。\n\nsmtp-relay.gmail.com:25だけでなく、smtp-relay.gmail.com:465が使えるので夢がある。\n\ngsuite Legacyはsmtp-relay.gmail.comに認証可能だが、メール配送で`relay denied. Invalid credentials for relay for`になり配送は拒否された。\n\n#### XOAUTH2とOAUTH トークン\n\nXOAUTH2 は OAUTH2トークンを以下のような文字列にし、PASSWORDの代わりに使うものである。\n```\nbase64(\"user=\" + userName + \"^Aauth=Bearer \" + accessToken + \"^A^A\")\n```\n\nruby のNet::SMTP::Authenticator::AuthXoauth2の実装がシンプルで読みやすい。\n```ruby\ntoken = \"user=#{user}\\1auth=Bearer #{secret}\\1\\1\"\nsmpt_mesg = \"AUTH XOAUTH2 #{base64_encode(token)}\"\n```\n\n## 参考資料\n\n- https://www.itline.jp/~svx/diary/20230818.html\n- https://unix.stackexchange.com/questions/584125/postfix-using-oauth2-authentication-for-relay-host\n- https://salsa.debian.org/uwabami/libsasl2-module-xoauth2\n- https://github.com/moriyoshi/cyrus-sasl-xoauth2\n- https://github.com/tarickb/sasl-xoauth2\n- https://takuya-1st.hatenablog.jp/entry/2023/12/27/153000\n- https://takuya-1st.hatenablog.jp/entry/2022/03/14/175433\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftakuya%2Fruby-google-xoauth2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftakuya%2Fruby-google-xoauth2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftakuya%2Fruby-google-xoauth2/lists"}