=================================
「丸坊主」の英語を「スキンヘッド」と覚えている人は要注意!
=================================
日本では髪を剃り上げたヘアスタイル、いわゆる丸坊主のことを「スキンヘッド」と言う習慣があるそうですが、英語で「Skin-head」というと、単に髪を剃り上げた人のことを指すのではなく、ギャングなど「危ない人」や「危険な人」を連想させるので使い方に注意が必要です。今日は「Skin-head」はどんな人なのか、また「坊主頭」の正しい英語表現をご紹介します。
--------------------------------------------------
1) Skin-head
→「スキンヘッド」
--------------------------------------------------
“Skin”は「肌」、“Head”は「頭」を意味することから、“Skin-head”はカミソリで髪の毛をツルツルに剃り上げるスタイルを表しますが、英語で“Skin-head”というと、“Gang member(不良)”や、白人至上主義者集団などの異民族に暴力行為を引き起こし兼ねない危ない人のイメージがあります。但し、これはあくまで固定概念であり、全てのスキンヘッドの人がそうというわけではありません。下記でも紹介していますが、単にヘアースタイルとしてのスキンヘッドを表現する場合は“Bald”を使いましょう。
<例文>
I saw a skin-head today.
(今日、スキンヘッドの人を見かけました。)
He was a skin-head with a lot of tattoos.
(彼は入れ墨が入ったスキンヘッドをしていました。)
There are a lot of skin-heads in that area.
(あの辺りは、スキンヘッドの人が多いです。)
--------------------------------------------------
2) Shaved head
→「丸坊主」
--------------------------------------------------
髪の毛を全部短く刈ったヘアスタイル、いわゆる「坊主頭」を英語で表すと“Shaved head”となります。“Shave”は「剃る」を意味しますが、カミソリでツルツルに剃るスタイルでなく、バリカンなどで髪の毛全体を短くするスタイルを表します。日本の高校野球児をイメージしたら分かりやすいと思います。このフレーズは“Skin-head”のように危険な印象はありません。
✔「坊主にする」→「Shave one's head」
<例文>
Tim has a shaved head.
(ティムは丸坊主です。)
I'm going to shave my head today.
(今日、丸坊主にします。)
Have you ever shaved your head?
(今までに丸坊主にしたことってある?)
--------------------------------------------------
3) Bald
→「ハゲ/スキンヘッド」
--------------------------------------------------
「ハゲ頭」は英語で“Bald”といいます。この表現は基本的に完全にはげている人を指し、髪の毛が全くない状態を表します。また、カミソリで頭をツルツルに剃っているヘアースタイル、いわゆるスキンヘッドのことも“Bald”と表現します。
✔“Bald head”と言う場合もある。
✔「多少ハゲている人」→「Kind of bald」
✔「ハゲてきた(人)」→「◯◯ is balding」「◯◯ is starting to bald」
<例文>
Mr. Smith is bald.
(スミスさんは完全にハゲています。)
Oh no. I think I'm balding.
(どうしよう、ハゲてきてる気がする。)
You know Peter, the guy with a shinny bald head.
(ツルツルのスキンヘッドのピーターって知ってるでしょ?)
※この場合は意図的にスキンヘッドにしているニュアンス。
--------------------------------------------------
) Buzz cut
→「スポーツ刈り」
--------------------------------------------------
トップを多少長めにして両サイドとバックを刈り上げたヘアースタイル「スペーツ刈り」は一般的に“Buzz cut”と表します。“Buzz cut”のバリエーションはいくつもありますが、アメリカでは一般的に髪の毛が短いショートヘアーを指します。
<例文>
Jason is the guy with a buzz cut.
(ジェイソンはスポーツ刈りの人です。)
I think I'm going to get a buzz cut.
(スポーツ刈りにしようと思っています。)
The buzz cut looks good on you.
(スポーツ刈りが似合ってるじゃん。)
~~~~~~~~~~~~~~~~~~~
無料メルマガ『1日1フレーズ!生英語』配信中!
通勤・通学などのちょとした合間を利用して英語が学べるメルマガ『1日1フレーズ!生英語』を平日の毎朝6時に配信中!ただ単にフレーズを紹介しているだけではなく、音声を使った学習プロセスが組み込まれているので、メルマガを読むこと自体が学習方法!
https://hapaeikaiwa.com/mailmagazine/
~~~~~~~~~~~~~~~~~~~
同時也有27部Youtube影片,追蹤數超過160萬的網紅ブライトサイド | Bright Side Japan,也在其Youtube影片中提到,自分の体に関する最もクールな事実は何だと思いですか? 目覚まし時計が鳴る前に目を覚めること? それとも、呼吸しながらだと物を飲み込めないということ? それか、まばたきの瞬間に超短い昼寝をしているということ? 人体は細かいところまで様々な機能を持つ機械のようなものなのです。 この繊細な機械がどのように...
「サイド 英語」的推薦目錄:
- 關於サイド 英語 在 Hapa Eikaiwa Facebook 的最佳貼文
- 關於サイド 英語 在 Hapa Eikaiwa Facebook 的最佳解答
- 關於サイド 英語 在 Hapa Eikaiwa Facebook 的最佳貼文
- 關於サイド 英語 在 ブライトサイド | Bright Side Japan Youtube 的最佳貼文
- 關於サイド 英語 在 ブライトサイド | Bright Side Japan Youtube 的最讚貼文
- 關於サイド 英語 在 ブライトサイド | Bright Side Japan Youtube 的最讚貼文
- 關於サイド 英語 在 YOASOBI 1st English EP"E-SIDE" Cross Fade Movie (第一弾 ... 的評價
- 關於サイド 英語 在 OAuth 2.0 Flow: Server-side web apps | YouTube Data API 的評價
サイド 英語 在 Hapa Eikaiwa Facebook 的最佳解答
=================================
「丸坊主」の英語を「スキンヘッド」と覚えている人は要注意!
=================================
日本では髪を剃り上げたヘアスタイル、いわゆる丸坊主のことを「スキンヘッド」と言う習慣があるそうですが、英語で「Skin-head」というと、単に髪を剃り上げた人のことを指すのではなく、ギャングなど「危ない人」や「危険な人」を連想させるので使い方に注意が必要です。今日は「Skin-head」はどんな人なのか、また「坊主頭」の正しい英語表現をご紹介します。
--------------------------------------------------
1) Skin-head
→「スキンヘッド」
--------------------------------------------------
“Skin”は「肌」、“Head”は「頭」を意味することから、“Skin-head”はカミソリで髪の毛をツルツルに剃り上げるスタイルを表しますが、英語で“Skin-head”というと、“Gang member(不良)”や、白人至上主義者集団などの異民族に暴力行為を引き起こし兼ねない危ない人のイメージがあります。但し、これはあくまで固定概念であり、全てのスキンヘッドの人がそうというわけではありません。下記でも紹介していますが、単にヘアースタイルとしてのスキンヘッドを表現する場合は“Bald”を使いましょう。
<例文>
I saw a skin-head today.
(今日、スキンヘッドの人を見かけました。)
He was a skin-head with a lot of tattoos.
(彼は入れ墨が入ったスキンヘッドをしていました。)
There are a lot of skin-heads in that area.
(あの辺りは、スキンヘッドの人が多いです。)
--------------------------------------------------
2) Shaved head
→「丸坊主」
--------------------------------------------------
髪の毛を全部短く刈ったヘアスタイル、いわゆる「坊主頭」を英語で表すと“Shaved head”となります。“Shave”は「剃る」を意味しますが、カミソリでツルツルに剃るスタイルでなく、バリカンなどで髪の毛全体を短くするスタイルを表します。日本の高校野球児をイメージしたら分かりやすいと思います。このフレーズは“Skin-head”のように危険な印象はありません。
✔「坊主にする」→「Shave one's head」
<例文>
Tim has a shaved head.
(ティムは丸坊主です。)
I'm going to shave my head today.
(今日、丸坊主にします。)
Have you ever shaved your head?
(今までに丸坊主にしたことってある?)
--------------------------------------------------
3) Bald
→「ハゲ/スキンヘッド」
--------------------------------------------------
「ハゲ頭」は英語で“Bald”といいます。この表現は基本的に完全にはげている人を指し、髪の毛が全くない状態を表します。また、カミソリで頭をツルツルに剃っているヘアースタイル、いわゆるスキンヘッドのことも“Bald”と表現します。
✔“Bald head”と言う場合もある。
✔「多少ハゲている人」→「Kind of bald」
✔「ハゲてきた(人)」→「◯◯ is balding」「◯◯ is starting to bald」
<例文>
Mr. Smith is bald.
(スミスさんは完全にハゲています。)
Oh no. I think I'm balding.
(どうしよう、ハゲてきてる気がする。)
You know Peter, the guy with a shinny bald head.
(ツルツルのスキンヘッドのピーターって知ってるでしょ?)
※この場合は意図的にスキンヘッドにしているニュアンス。
--------------------------------------------------
) Buzz cut
→「スポーツ刈り」
--------------------------------------------------
トップを多少長めにして両サイドとバックを刈り上げたヘアースタイル「スペーツ刈り」は一般的に“Buzz cut”と表します。“Buzz cut”のバリエーションはいくつもありますが、アメリカでは一般的に髪の毛が短いショートヘアーを指します。
<例文>
Jason is the guy with a buzz cut.
(ジェイソンはスポーツ刈りの人です。)
I think I'm going to get a buzz cut.
(スポーツ刈りにしようと思っています。)
The buzz cut looks good on you.
(スポーツ刈りが似合ってるじゃん。)
~~~~~~~~~~~~~~~~~~~
無料メルマガ『1日1フレーズ!生英語』配信中!
通勤・通学などのちょとした合間を利用して英語が学べるメルマガ『1日1フレーズ!生英語』を平日の毎朝6時に配信中!ただ単にフレーズを紹介しているだけではなく、音声を使った学習プロセスが組み込まれているので、メルマガを読むこと自体が学習方法!
https://hapaeikaiwa.com/mailmagazine/
~~~~~~~~~~~~~~~~~~~
サイド 英語 在 Hapa Eikaiwa Facebook 的最佳貼文
=================================
「丸坊主」の英語を「スキンヘッド」と覚えている人は要注意!
=================================
日本では髪を剃り上げたヘアスタイル、いわゆる丸坊主のことを「スキンヘッド」と言う習慣があるそうですが、英語で「Skin-head」というと、単に髪を剃り上げた人のことを指すのではなく、ギャングなど「危ない人」や「危険な人」を連想させるので使い方に注意が必要です。今日は「Skin-head」はどんな人なのか、また「坊主頭」の正しい英語表現をご紹介します。
--------------------------------------------------
1) Skin-head
→「スキンヘッド」
--------------------------------------------------
“Skin”は「肌」、“Head”は「頭」を意味することから、“Skin-head”はカミソリで髪の毛をツルツルに剃り上げるスタイルを表しますが、英語で“Skin-head”というと、“Gang member(不良)”や、白人至上主義者集団などの異民族に暴力行為を引き起こし兼ねない危ない人のイメージがあります。但し、これはあくまで固定概念であり、全てのスキンヘッドの人がそうというわけではありません。下記でも紹介していますが、単にヘアースタイルとしてのスキンヘッドを表現する場合は“Bald”を使いましょう。
<例文>
I saw a skin-head today.
(今日、スキンヘッドの人を見かけました。)
He was a skin-head with a lot of tattoos.
(彼は入れ墨が入ったスキンヘッドをしていました。)
There are a lot of skin-heads in that area.
(あの辺りは、スキンヘッドの人が多いです。)
--------------------------------------------------
2) Shaved head
→「丸坊主」
--------------------------------------------------
髪の毛を全部短く刈ったヘアスタイル、いわゆる「坊主頭」を英語で表すと“Shaved head”となります。“Shave”は「剃る」を意味しますが、カミソリでツルツルに剃るスタイルでなく、バリカンなどで髪の毛全体を短くするスタイルを表します。日本の高校野球児をイメージしたら分かりやすいと思います。このフレーズは“Skin-head”のように危険な印象はありません。
✔「坊主にする」→「Shave one's head」
<例文>
Tim has a shaved head.
(ティムは丸坊主です。)
I'm going to shave my head today.
(今日、丸坊主にします。)
Have you ever shaved your head?
(今までに丸坊主にしたことってある?)
--------------------------------------------------
3) Bald
→「ハゲ/スキンヘッド」
--------------------------------------------------
「ハゲ頭」は英語で“Bald”といいます。この表現は基本的に完全にはげている人を指し、髪の毛が全くない状態を表します。また、カミソリで頭をツルツルに剃っているヘアースタイル、いわゆるスキンヘッドのことも“Bald”と表現します。
✔“Bald head”と言う場合もある。
✔「多少ハゲている人」→「Kind of bald」
✔「ハゲてきた(人)」→「◯◯ is balding」「◯◯ is starting to bald」
<例文>
Mr. Smith is bald.
(スミスさんは完全にハゲています。)
Oh no. I think I'm balding.
(どうしよう、ハゲてきてる気がする。)
You know Peter, the guy with a shinny bald head.
(ツルツルのスキンヘッドのピーターって知ってるでしょ?)
※この場合は意図的にスキンヘッドにしているニュアンス。
--------------------------------------------------
) Buzz cut
→「スポーツ刈り」
--------------------------------------------------
トップを多少長めにして両サイドとバックを刈り上げたヘアースタイル「スペーツ刈り」は一般的に“Buzz cut”と表します。“Buzz cut”のバリエーションはいくつもありますが、アメリカでは一般的に髪の毛が短いショートヘアーを指します。
<例文>
Jason is the guy with a buzz cut.
(ジェイソンはスポーツ刈りの人です。)
I think I'm going to get a buzz cut.
(スポーツ刈りにしようと思っています。)
The buzz cut looks good on you.
(スポーツ刈りが似合ってるじゃん。)
~~~~~~~~~~~~~~~~~~~
無料メルマガ『1日1フレーズ!生英語』配信中!
通勤・通学などのちょとした合間を利用して英語が学べるメルマガ『1日1フレーズ!生英語』を平日の毎朝6時に配信中!ただ単にフレーズを紹介しているだけではなく、音声を使った学習プロセスが組み込まれているので、メルマガを読むこと自体が学習方法!
https://hapaeikaiwa.com/mailmagazine/
~~~~~~~~~~~~~~~~~~~
サイド 英語 在 ブライトサイド | Bright Side Japan Youtube 的最佳貼文
自分の体に関する最もクールな事実は何だと思いですか? 目覚まし時計が鳴る前に目を覚めること? それとも、呼吸しながらだと物を飲み込めないということ? それか、まばたきの瞬間に超短い昼寝をしているということ? 人体は細かいところまで様々な機能を持つ機械のようなものなのです。 この繊細な機械がどのように機能しているのか興味がありませんか? 今回は人体に関する事実といろいろな機能に関する理由を学んでみましょう。
ストックマテリアル (写真、動画など):
https://www.depositphotos.com
https://www.shutterstock.com
https://www.eastnews.ru
エピデミックサウンド https://www.epidemicsound.com/
ブライトサイドのチャンネル登録 https://goo.gl/31w525
-------------------------------------------------------------------------------------------
声の提供
さくらい声優事務所
サイド 英語 在 ブライトサイド | Bright Side Japan Youtube 的最讚貼文
人間は空気なしで3分間、水なしで3日間、食べ物なしで3週間以上生きることはできないと言われています。 でも、世の中には人間の生存能力の限界を超えることに成功した珍しい世界記録保持者たちがいます! 息を止めたり、食べ物や、水や、睡眠なしで生き残った最長記録はどれくらいなのか、一緒に見てみましょう!
ストックマテリアル (写真、動画など):
https://www.depositphotos.com
https://www.shutterstock.com
https://www.eastnews.ru
エピデミックサウンド https://www.epidemicsound.com/
ブライトサイドのチャンネル登録 https://goo.gl/31w525
-------------------------------------------------------------------------------------------
声の提供
さくらい声優事務所
サイド 英語 在 ブライトサイド | Bright Side Japan Youtube 的最讚貼文
今回は多く人々が知らない人体に関する驚くべき事実を学んでみましょう! 大半の人には見られない珍しい体の特徴をご紹介します。 自分が地球上でユニークな人々の中の一人だと思いますか? では、自分の体に珍しい特徴があるかどうかチェックしてみましょう!
#ブライトサイド
ストックマテリアル (写真、動画など):
https://www.depositphotos.com
https://www.shutterstock.com
https://www.eastnews.ru
エピデミックサウンド https://www.epidemicsound.com/
ブライトサイドのチャンネル登録 https://goo.gl/31w525
-------------------------------------------------------------------------------------------
声の提供
さくらい声優事務所
サイド 英語 在 OAuth 2.0 Flow: Server-side web apps | YouTube Data API 的推薦與評價
このドキュメントでは、ウェブサーバー アプリケーションが Google API クライアント ライブラリまたは Google OAuth 2.0 エンドポイントを使用して、YouTube Data API にアクセスするための OAuth 2.0 認可を実装する方法を説明します。
OAuth 2.0 では、ユーザー名やパスワードなどの情報を秘密にしたまま、ユーザーが特定のデータをアプリケーションと共有できます。たとえば、アプリケーションで OAuth 2.0 を使い、ユーザーの YouTube チャンネルに動画をアップロードする権限を取得できます。
この OAuth 2.0 フローは、ユーザー認可専用です。機密情報を保存して状態を維持できるアプリケーション向けに設計されています。適切に承認されたウェブサーバー アプリケーションは、ユーザーがアプリケーションを操作している間、またはユーザーがアプリケーションを終了した後に API にアクセスできます。
ウェブサーバー アプリケーションでは、特に Cloud APIs を呼び出してユーザー固有のデータではなくプロジェクトベースのデータにアクセスする場合、
サービス アカウントを使用して API リクエストを承認することもよくあります。ウェブサーバー アプリケーションは、ユーザー認可と組み合わせてサービス アカウントを使用できます。YouTube Data API は、複数の YouTube チャンネルを所有して管理している YouTube コンテンツ所有者のみがサービス アカウントのフローをサポートします。具体的には、コンテンツ所有者はサービス アカウントを使用して、onBehalfOfContentOwner
リクエスト パラメータをサポートする API メソッドを呼び出すことができます。
注: 適切に実装した場合のセキュリティ上の影響を考慮すると、Google の OAuth 2.0 エンドポイントとやり取りする際は OAuth 2.0 ライブラリを使用することを強くおすすめします。他のユーザーから提供された、適切にデバッグされたコードを使用することをおすすめします。これはデベロッパーとユーザーを保護するのに役立ちます。詳細については、クライアント ライブラリをご覧ください。
クライアント ライブラリ
このページの言語固有のサンプルでは、Google API クライアント ライブラリを使用して OAuth 2.0 認証を実装しています。サンプルコードを実行するには、ご利用の言語のクライアント ライブラリをインストールしてください。
Google API クライアント ライブラリを使用してアプリケーションの OAuth 2.0 フローを処理すると、アプリケーションが独自に処理する必要のある多くのアクションをクライアント ライブラリが実行します。たとえば、アプリが保存されているアクセス トークンを使用または更新できるタイミングや、アプリが同意を再度取得する必要があるタイミングを決定します。クライアント ライブラリは、正しいリダイレクト URL を生成し、認証コードをアクセス トークンと交換するリダイレクト ハンドラの実装にも役立ちます。
サーバーサイド アプリケーション用の Google API クライアント ライブラリは、次の言語で利用できます。
Go
Java
.NET
Node.js
PHP
Python
Ruby
重要: JavaScript 用 Google API クライアント ライブラリと Google でログインは、ユーザーのブラウザで OAuth 2.0 を処理することを目的としています。のみサーバーサイドで JavaScript を使用して Google との OAuth 2.0 インタラクションを管理する場合は、バックエンド プラットフォームで Node.js ライブラリの使用を検討してください。
前提条件
プロジェクトでAPI を有効にする
Google API を呼び出すアプリケーションは、 API Consoleでこれらの API を有効にする必要があります。
プロジェクトで API を有効にするには:
Google API ConsoleのOpen the API Library 。
If prompted, select a project, or create a new one. [ライブラリ] ページで、YouTube Data API を見つけて有効にします。アプリケーションで使用する他の API を見つけて、それらも有効にします。
承認認証情報を作成する
OAuth 2.0 を使用して Google API にアクセスするアプリケーションは、Google の OAuth 2.0 サーバーに対して自身の身元を示す認証情報を持つ必要があります。次の手順では、プロジェクトの認証情報を作成する方法について説明します。アプリケーションは、その認証情報を使用して、そのプロジェクトで有効にした API にアクセスできます。
Go to the Credentials page.
[認証情報を作成] > [OAuth クライアント ID] をクリックします。
アプリケーションの種類として [ウェブ アプリケーション] を選択します。
フォームに記入し、[作成] をクリックします。PHP、Java、Python、Ruby、.NET などの言語とフレームワークを使用するアプリケーションでは、承認済みのリダイレクト URI を指定する必要があります。リダイレクト URI は、OAuth 2.0 サーバーがレスポンスを送信できるエンドポイントです。これらのエンドポイントは、Google の検証ルールに準拠している必要があります。
テストでは、ローカルマシンを参照する URI(http://localhost:8080
など)を指定できます。このドキュメントの例では、すべてリダイレクト URI として http://localhost:8080
を使用しています。
アプリケーションで認証コードがページ上の他のリソースに公開されないように、アプリの認証エンドポイントを設計することをおすすめします。
認証情報を作成したら、 API Consoleから client_secret.json ファイルをダウンロードします。ご使用のアプリケーションだけがアクセスできる場所に、ファイルを安全に保存します。
重要: client_secret.json ファイルを一般公開されている場所に保存しないでください。また、GitHub などでアプリケーションのソースコードを共有する場合は、クライアント認証情報を誤って共有しないように、client_secret.json ファイルをソースツリーの外に保存してください。アクセス スコープを特定する
スコープを指定すると、アプリケーションからのアクセス要求は必要なリソースのみに限定されるようになり、ユーザーはアプリケーションに付与するアクセスレベルを制御できます。そのため、リクエストするスコープの数とユーザーの同意を得られる可能性との間には逆相関関係がある可能性があります。
OAuth 2.0 認証の実装を開始する前に、アプリがアクセス権限を必要とするスコープを設定しておくことをおすすめします。
また、アプリケーションが段階的な認可プロセスを介して認可スコープへのアクセスをリクエストすることをおすすめします。このプロセスでは、アプリケーションがコンテキスト内のユーザーデータへのアクセスをリクエストします。このベスト プラクティスにより、アプリがリクエストしているアクセス権が必要な理由をユーザーが理解しやすくなります。
YouTube Data API v3 は、次のスコープを使用します。
スコープ
https://www.googleapis.com/auth/youtubeYouTube アカウントの管理
https://www.googleapis.com/auth/youtube.channel-memberships.creator現在アクティブなチャンネル メンバー、メンバーの現在のレベル、いつメンバーになったかをリストで確認する
https://www.googleapis.com/auth/youtube.force-sslYouTube 動画、評価、コメント、字幕の表示、編集、完全削除
https://www.googleapis.com/auth/youtube.readonlyYouTube アカウントの表示
https://www.googleapis.com/auth/youtube.uploadYouTube 動画の管理
https://www.googleapis.com/auth/youtubepartnerYouTube のアセットや関連するコンテンツの表示と管理
https://www.googleapis.com/auth/youtubepartner-channel-auditYouTube パートナーの監査プロセス時に関連する YouTube チャンネルの個人情報の表示
OAuth 2.0 API スコープのドキュメントには、Google API へのアクセスに使用できるスコープの完全なリストが記載されています。
一般公開アプリケーションが、特定のユーザーデータへのアクセスを許可するスコープを使用している場合は、確認プロセスを完了する必要があります。アプリケーションのテストを行っている際、画面に未確認アプリが表示された場合、確認リクエストを送信してその表示を削除する必要があります。未確認アプリの詳細と、
アプリの確認に関するよくある質問については、ヘルプセンターをご覧ください。
言語固有の要件
このドキュメントのコードのいずれかを実行するには、Google アカウント、インターネットへのアクセス、ウェブブラウザが必要です。API クライアント ライブラリのいずれかを使用している場合は、以下の言語固有の要件もご覧ください。
このドキュメントの PHP コードサンプルを実行するには、次のものが必要です。
コマンドライン インターフェース(CLI)と JSON 拡張機能がインストールされた PHP 8.0 以降。
Composer 依存関係管理ツール。
PHP 用 Google API クライアント ライブラリ:
composer require google/apiclient:^2.15.0
詳細については、PHP 用 Google API クライアント ライブラリをご覧ください。
Pythonこのドキュメントの Python コードサンプルを実行するには、次のものが必要です。
Python 3.7 以降
pip パッケージ管理ツール。
Python 用 Google API クライアント ライブラリ 2.0 リリース:
pip install --upgrade google-api-python-client
ユーザー認証用の
google-auth
、google-auth-oauthlib
、google-auth-httplib2
。
pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
Flask Python ウェブ アプリケーション フレームワーク。
pip install --upgrade flask
requests
HTTP ライブラリ。
pip install --upgrade requests
Python をアップグレードできない場合は、Google API Python クライアント ライブラリのリリースノートと関連する移行ガイドをご覧ください。
Rubyこのドキュメントの Ruby コードサンプルを実行するには、次のものが必要です。
Ruby 2.6 以降
Ruby 用 Google 認証ライブラリ:
gem install googleauth
Sinatra Ruby ウェブ アプリケーション フレームワーク。
gem install sinatra
Node.js
このドキュメントの Node.js コードサンプルを実行するには、次のものが必要です。
Node.js のメンテナンス LTS、アクティブ LTS、または最新のリリース。
Google API Node.js クライアント:
npm install googleapis crypto express express-session
HTTP/REST
OAuth 2.0 エンドポイントを直接呼び出すためにライブラリをインストールする必要はありません。
OAuth 2.0 アクセス トークンの取得
次の手順は、アプリケーションが Google の OAuth 2.0 サーバーとやり取りして、ユーザーに代わって API リクエストを実行するためのユーザーの同意を得る方法を示しています。ユーザーの承認が必要な Google API リクエストを実行するには、アプリがその同意を得ている必要があります。
以下のリストに、これらの手順を簡単にまとめます。
アプリが必要な権限を特定します。
リクエストされた権限のリストとともに、ユーザーを Google にリダイレクトします。
ユーザーがアプリに権限を付与するかどうかを決定します。
ユーザーが何を決めたかをアプリが把握します。
ユーザーがリクエストされた権限を付与すると、アプリはユーザーに代わって API リクエストを行うために必要なトークンを取得します。
ステップ 1: 認可パラメータを設定する
まず、認可リクエストを作成します。このリクエストでは、アプリを識別するパラメータを設定し、ユーザーにアプリへの権限付与を求める権限を定義します。
OAuth 2.0 の認証と承認に Google クライアント ライブラリを使用する場合は、これらのパラメータを定義するオブジェクトを作成して構成します。
Google OAuth 2.0 エンドポイントを直接呼び出す場合は、URL を生成し、その URL にパラメータを設定します。
次のタブでは、ウェブサーバー アプリケーションでサポートされている認可パラメータを定義します。言語固有のサンプルでは、クライアント ライブラリまたは認可ライブラリを使用して、これらのパラメータを設定するオブジェクトを構成する方法も示しています。
次のコード スニペットは、認可リクエストのパラメータを定義する Google\Client()
オブジェクトを作成します。
このオブジェクトは、client_secret.json ファイルの情報を使用してアプリケーションを識別します。(このファイルの詳細については、認証情報の作成をご覧ください)。このオブジェクトは、アプリケーションがアクセス権をリクエストしているスコープと、Google の OAuth 2.0 サーバーからのレスポンスを処理するアプリケーションの認証エンドポイントの URL も識別します。最後に、オプションの access_type
パラメータと include_granted_scopes
パラメータを設定します。
たとえば、次のコードは、ユーザーの YouTube アカウントを管理するためのオフライン アクセスをリクエストします。
use Google\Client;$client = new Client();// Required, call the setAuthConfig function to load authorization credentials fromPython
// client_secret.json file.
$client->setAuthConfig('client_secret.json');// Required, to set the scope value, call the addScope function
$client->addScope(GOOGLE_SERVICE_YOUTUBE::YOUTUBE_FORCE_SSL);// Required, call the setRedirectUri function to specify a valid redirect URI for the
// provided client_id
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');// Recommended, call the setState function. Using a state value can increase your assurance that
// an incoming connection is the result of an authentication request.
$client->setState($sample_passthrough_value);// Optional, if your application knows which user is trying to authenticate, it can use this
// parameter to provide a hint to the Google Authentication Server.
$client->setLoginHint('hint@example.com');// Optional, call the setPrompt function to set "consent" will prompt the user for consent
$client->setPrompt('consent');// Optional, call the setIncludeGrantedScopes function with true to enable incremental
// authorization
$client->setIncludeGrantedScopes(true);
次のコード スニペットは、google-auth-oauthlib.flow
モジュールを使用して認可リクエストを作成します。
このコードは、認可認証情報の作成後にダウンロードした client_secret.json ファイルの情報を使用して、アプリケーションを識別する Flow
オブジェクトを作成します。このオブジェクトは、アプリケーションがアクセス権をリクエストしているスコープと、Google の OAuth 2.0 サーバーからのレスポンスを処理するアプリケーションの認証エンドポイントの URL も識別します。最後に、コードは省略可能な access_type
パラメータと include_granted_scopes
パラメータを設定します。
たとえば、次のコードは、ユーザーの YouTube アカウントを管理するためのオフライン アクセスをリクエストします。
import google.oauth2.credentialsRuby
import google_auth_oauthlib.flow# Required, call the from_client_secrets_file method to retrieve the client ID from a
# client_secret.json file. The client ID (from that file) and access scopes are required. (You can
# also use the from_client_config method, which passes the client configuration as it originally
# appeared in a client secrets file but doesn't access the file itself.)
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json',
scopes=['https://www.googleapis.com/auth/youtube.force-ssl'])# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
# Recommended, enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline',
# Optional, enable incremental authorization. Recommended as a best practice.
include_granted_scopes='true',
# Optional, if your application knows which user is trying to authenticate, it can use this
# parameter to provide a hint to the Google Authentication Server.
login_hint='hint@example.com',
# Optional, set prompt to 'consent' will prompt the user for consent
prompt='consent')
作成した client_secrets.json ファイルを使用して、アプリケーションでクライアント オブジェクトを構成します。クライアント オブジェクトを構成するときに、アプリケーションがアクセスする必要があるスコープと、OAuth 2.0 サーバーからのレスポンスを処理するアプリケーションの認証エンドポイントの URL を指定します。
たとえば、次のコードは、ユーザーの YouTube アカウントを管理するためのオフライン アクセスをリクエストします。
require 'googleauth'
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'require 'google/apis/youtube_v3'# Required, call the from_file method to retrieve the client ID from a
# client_secret.json file.
client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')# Required, scope value
scope = 'https://www.googleapis.com/auth/youtube.force-ssl'# Required, Authorizers require a storage instance to manage long term persistence of
# access and refresh tokens.
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
callback_uri = '/oauth2callback'# To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
# from the client_secret.json file. To get these credentials for your application, visit
# https://console.cloud.google.com/apis/credentials.
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope,
token_store, callback_uri)
アプリケーションは、クライアント オブジェクトを使用して、認可リクエスト URL の生成や HTTP リクエストへのアクセス トークンの適用などの OAuth 2.0 オペレーションを実行します。
Node.js
次のコード スニペットは、認可リクエストのパラメータを定義する google.auth.OAuth2
オブジェクトを作成します。
このオブジェクトは、client_secret.json ファイルの情報を使用してアプリケーションを識別します。アクセス トークンを取得する権限をユーザーにリクエストするには、同意ページにリダイレクトします。同意ページの URL を作成するには:
const {google} = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');/**
* To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
* from the client_secret.json file. To get these credentials for your application, visit
* https://console.cloud.google.com/apis/credentials.
*/
const oauth2Client = new google.auth.OAuth2(
YOUR_CLIENT_ID,
YOUR_CLIENT_SECRET,
YOUR_REDIRECT_URL
);// Access scopes for YouTube API
const scopes = [
'https://www.googleapis.com/auth/youtube.force-ssl'
];// Generate a secure random state value.
const state = crypto.randomBytes(32).toString('hex');// Store state in the session
req.session.state = state;// Generate a url that asks permissions for the Drive activity and Google Calendar scope
const authorizationUrl = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',
/** Pass in the scopes array defined above.
* Alternatively, if only one scope is needed, you can pass a scope URL as a string */
scope: scopes,
// Enable incremental authorization. Recommended as a best practice.
include_granted_scopes: true,
// Include the state parameter to reduce the risk of CSRF attacks.
state: state
});
重要な注意事項 - refresh_token
は最初の認可時にのみ返されます。詳しくは、
こちらをご覧ください。
Google の OAuth 2.0 エンドポイントは https://accounts.google.com/o/oauth2/v2/auth
にあります。このエンドポイントには HTTPS 経由でのみアクセスできます。プレーン HTTP 接続は拒否されます。
Google 認可サーバーは、ウェブサーバー アプリケーションの次のクエリ文字列パラメータをサポートしています。
パラメータ
client_id
必須
アプリケーションのクライアント ID。この値は、 API Console
Credentials pageにあります。
redirect_uri
必須
ユーザーが認可フローを完了した後に API サーバーがユーザーをリダイレクトする場所を決定します。この値は、クライアントの API Console
Credentials pageで構成した OAuth 2.0 クライアントの承認済みリダイレクト URI のいずれかと完全に一致している必要があります。この値が、指定された client_id
の承認済みリダイレクト URI と一致しない場合、redirect_uri_mismatch
エラーが発生します。
http
または https
のスキーマ、大文字と小文字、末尾のスラッシュ(/
)はすべて一致する必要があります。
response_type
必須
Google OAuth 2.0 エンドポイントが認可コードを返すかどうかを決定します。
ウェブサーバー アプリケーションの場合は、パラメータ値を code
に設定します。
scope
必須
アプリケーションがユーザーに代わってアクセスできるリソースを識別するスコープのスペース区切りリスト。これらの値は、Google がユーザーに表示する同意画面に通知されます。
スコープを指定すると、アプリケーションからのアクセス要求は必要なリソースのみに限定されるようになり、ユーザーはアプリケーションに付与するアクセスレベルを制御できます。したがって、リクエストするスコープの数とユーザーの同意を得られる可能性との間には逆相関関係があります。
YouTube Data API v3 は、次のスコープを使用します。
スコープ
https://www.googleapis.com/auth/youtubeYouTube アカウントの管理
https://www.googleapis.com/auth/youtube.channel-memberships.creator現在アクティブなチャンネル メンバー、メンバーの現在のレベル、いつメンバーになったかをリストで確認する
https://www.googleapis.com/auth/youtube.force-sslYouTube 動画、評価、コメント、字幕の表示、編集、完全削除
https://www.googleapis.com/auth/youtube.readonlyYouTube アカウントの表示
https://www.googleapis.com/auth/youtube.uploadYouTube 動画の管理
https://www.googleapis.com/auth/youtubepartnerYouTube のアセットや関連するコンテンツの表示と管理
https://www.googleapis.com/auth/youtubepartner-channel-auditYouTube パートナーの監査プロセス時に関連する YouTube チャンネルの個人情報の表示
OAuth 2.0 API スコープのドキュメントでは、Google API へのアクセスに使用できるスコープの一覧を確認できます。
可能な限り、アプリケーションでコンテキスト内の認可スコープへのアクセスをリクエストすることをおすすめします。段階的認証を使用して、コンテキストに沿ってユーザーデータへのアクセス権をリクエストすると、アプリがリクエストしているアクセス権が必要な理由をユーザーが理解しやすくなります。
access_type
推奨
ユーザーがブラウザにいないときに、アプリケーションがアクセス トークンを更新できるかどうかを示します。有効なパラメータ値は、デフォルト値の online
と offline
です。
ユーザーがブラウザにいないときにアプリでアクセス トークンを更新する必要がある場合は、値を offline
に設定します。これは、このドキュメントの後半で説明するアクセス トークンを更新する方法です。この値は、アプリケーションが初めて認証コードをトークンと交換するときに、更新トークンとアクセス トークンを返すように Google 認可サーバーに指示します。
state
推奨
認可リクエストと認可サーバーのレスポンス間で状態を維持するために、アプリケーションが使用する文字列値を指定します。ユーザーがアプリのアクセス リクエストに同意または拒否すると、サーバーは redirect_uri
の URL クエリ コンポーネント(?
)で name=value
ペアとして送信された正確な値を返します。
このパラメータは、アプリケーション内の正しいリソースにユーザーを誘導する、ノンスを送信する、クロスサイト リクエストのなりすましを軽減するなど、さまざまな目的で使用できます。redirect_uri
は推測される可能性があるため、state
値を使用すると、受信接続が認証リクエストの結果であることを確認できます。ランダムな文字列を生成する、または Cookie のハッシュやクライアントの状態をキャプチャする他の値をエンコードすると、レスポンスを検証して、リクエストとレスポンスが同じブラウザから発信されたことを確認できます。これにより、クロスサイト リクエストのなりすましなどの攻撃から保護できます。state
トークンの作成と確認方法の例については、OpenID Connect のドキュメントをご覧ください。
重要: OAuth クライアントは、OAuth2 仕様
で呼び出されているように CSRF を防止する必要があります。これを行う 1 つの方法は、
state
パラメータを使用して、認可リクエストと認可サーバーのレスポンス間の状態を維持することです。include_granted_scopes
省略可
アプリが段階的認可を使用して、コンテキスト内の追加のスコープへのアクセスをリクエストできるようにします。このパラメータの値を true
に設定し、認可リクエストが承認されると、新しいアクセス トークンは、ユーザーが以前にアプリにアクセス権を付与したスコープにも適用されます。例については、増分承認のセクションをご覧ください。
enable_granular_consent
省略可
デフォルトは true
です。false
に設定すると、2019 年より前に作成された OAuth クライアント ID に対して、よりきめ細かい Google アカウントの権限が無効になります。新しい OAuth クライアント ID には影響しません。新しい OAuth クライアント ID では、よりきめ細かい権限が常に有効になっています。
Google がアプリのきめ細かい権限を有効にすると、このパラメータは効果しなくなります。
login_hint
省略可
アプリケーションが認証を試行しているユーザーを把握している場合は、このパラメータを使用して Google 認証サーバーにヒントを提供できます。サーバーは、ログイン フォームのメール フィールドに事前入力するか、適切なマルチログイン セッションを選択することで、ログインフローを簡素化するためにヒントを使用します。
パラメータ値をメールアドレスまたは sub
ID(ユーザーの Google ID と同等)に設定します。
prompt
省略可
ユーザーに表示するプロンプトのリスト(スペース区切り、大文字と小文字を区別)。このパラメータを指定しない場合、ユーザーにプロンプトが表示されるのは、プロジェクトがアクセス権をリクエストした初回のみです。詳しくは、
再同意を求めるプロンプトをご覧ください。
次の値があります。
none
認証画面や同意画面は表示しないでください。他の値で指定しないでください。
consent
ユーザーに同意を求めるメッセージが表示されます。
select_account
アカウントを選択するようユーザーに求める。
ステップ 2: Google の OAuth 2.0 サーバーにリダイレクトする
ユーザーを Google の OAuth 2.0 サーバーにリダイレクトして、認証と承認のプロセスを開始します。通常、これは、アプリケーションがユーザーのデータに初めてアクセスする必要がある場合に発生します。増分認可の場合、このステップは、アプリがアクセス権を持っていない追加のリソースに初めてアクセスする必要がある場合にも行われます。
Google の OAuth 2.0 サーバーからアクセスをリクエストする URL を生成します。
$auth_url = $client->createAuthUrl();
ユーザーを
$auth_url
にリダイレクトします。header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Python
この例では、Flask ウェブ アプリケーション フレームワークを使用して、ユーザーを認可 URL にリダイレクトする方法を示します。
return flask.redirect(authorization_url)Ruby
Google の OAuth 2.0 サーバーからアクセスをリクエストする URL を生成します。
auth_uri = authorizer.get_authorization_url(request: request)
ユーザーを
auth_uri
にリダイレクトします。Node.js
ステップ 1
generateAuthUrl
メソッドで生成された URL authorizationUrl
を使用して、Google の OAuth 2.0 サーバーからアクセスをリクエストします。ユーザーを
authorizationUrl
にリダイレクトします。res.redirect(authorizationUrl);
HTTP/REST Google の認可サーバーにリダイレクトする例
以下のサンプル URL は、ユーザーの YouTube アカウントを表示するためのアクセス権を許可するスコープへのオフライン アクセス(access_type=offline
)をリクエストしています。増分認可を使用して、ユーザーが以前にアプリにアクセス権を付与したすべてのスコープが新しいアクセス トークンに含まれるようにします。URL では、必要な redirect_uri
、response_type
、client_id
パラメータと state
パラメータの値も設定します。URL には、読みやすくするために改行とスペースが含まれています。
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
access_type=offline&
include_granted_scopes=true&
state=state_parameter_passthrough_value&
redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
response_type=code&
client_id=client_id
リクエスト URL を作成したら、ユーザーをその URL にリダイレクトします。
Google の OAuth 2.0 サーバーがユーザーを認証し、リクエストされたスコープにアプリがアクセスすることに関してユーザーの同意を得ます。レスポンスは、指定したリダイレクト URL を使用してアプリケーションに返されます。
ステップ 3: Google がユーザーに同意を求めるメッセージが表示されるこのステップで、ユーザーはリクエストされたアクセスをアプリに許可するかどうかを決定します。この段階で、Google から同意ウィンドウが表示されます。このウィンドウには、アプリケーションの名前と、ユーザーの認証情報を使用してアクセス権限をリクエストしている Google API サービス、および付与されるアクセス スコープの概要が表示されます。ユーザーは、アプリがリクエストした 1 つ以上のスコープへのアクセス権の付与に同意するか、リクエストを拒否できます。
この段階では、アクセスが許可されたかどうかを示す Google の OAuth 2.0 サーバーからのレスポンスを待機するため、アプリケーションは何もする必要はありません。このレスポンスについては、次のステップで説明します。
エラー
Google の OAuth 2.0 認可エンドポイントへのリクエストで、想定される認証フローと認可フローの代わりに、ユーザー向けのエラー メッセージが表示されることがあります。一般的なエラーコードと推奨される解決策は次のとおりです。
admin_policy_enforced
Google Workspace 管理者のポリシーにより、リクエストされた 1 つ以上のスコープを Google アカウントが承認できません。OAuth クライアント ID にアクセス権が明示的に付与されるまで、管理者がすべてのスコープまたは機密性の高いスコープと制限付きスコープへのアクセスを制限する方法については、Google Workspace 管理者向けのヘルプ記事「
Google Workspace のデータにアクセスできるサードパーティ製アプリと内部アプリを制御する」をご覧ください。
disallowed_useragent
認可エンドポイントが、Google の OAuth 2.0 ポリシーで禁止されている埋め込みユーザー エージェントの内部に表示されている。
Android
Android デベロッパーが android.webkit.WebView
で認可リクエストを開くと、このエラー メッセージが表示されることがあります。代わりに、Android 版 Google ログインや OpenID Foundation の Android 版 AppAuth などの Android ライブラリを使用してください。
ウェブ デベロッパーは、Android アプリが埋め込まれたユーザー エージェントで一般的なウェブリンクを開き、ユーザーがサイトから Google の OAuth 2.0 認可エンドポイントに移動したときに、このエラーが発生することがあります。デベロッパーは、一般的なリンクをオペレーティング システムのデフォルトのリンク ハンドラで開くようにする必要があります。これには、Android アプリリンク ハンドラとデフォルトのブラウザ アプリの両方が含まれます。Android カスタムタブ ライブラリもサポートされているオプションです。
iOS
iOS と macOS のデベロッパーは、WKWebView
で承認リクエストを開いたときに、このエラーが発生することがあります。デベロッパーは、代わりに Google ログイン for iOS や OpenID Foundation の AppAuth for iOS などの iOS ライブラリを使用する必要があります。
ウェブ デベロッパーがこのエラーに遭遇するのは、iOS または macOS アプリが埋め込まれたユーザー エージェントで一般的なウェブリンクを開き、ユーザーがサイトから Google の OAuth 2.0 認可エンドポイントに移動した場合です。開発者は、一般的なリンクがオペレーティング システムのデフォルトのリンク ハンドラで開くようにする必要があります。これには、ユニバーサル リンク ハンドラとデフォルトのブラウザ アプリの両方が含まれます。SFSafariViewController
ライブラリもサポートされているオプションです。
org_internal
リクエストの OAuth クライアント ID は、特定の
Google Cloud 組織内の Google アカウントへのアクセスを制限するプロジェクトの一部です。この構成オプションの詳細については、OAuth 同意画面の設定に関するヘルプ記事のユーザーの種類をご覧ください。
invalid_client
OAuth クライアント シークレットが正しくありません。このリクエストに使用されたクライアント ID とシークレットなど、OAuth クライアントの構成を確認します。
invalid_grant
アクセス トークンを更新するときや増分認可を使用するときに、トークンが期限切れまたは無効になっている可能性があります。
ユーザーを再度認証し、新しいトークンを取得するためのユーザーの同意を求めます。このエラーが引き続き表示される場合は、アプリケーションが正しく構成されていること、およびリクエストで正しいトークンとパラメータを使用していることを確認してください。そうでない場合は、ユーザー アカウントが削除または無効になっている可能性があります。
redirect_uri_mismatch
認可リクエストで渡された redirect_uri
が、OAuth クライアント ID の承認済みリダイレクト URI と一致しません。 Google API Console Credentials pageで承認済みのリダイレクト URI を確認します。
redirect_uri
パラメータは、非推奨でサポートされていない OAuth 帯域外(OOB)フローを参照している可能性があります。統合を更新するには、移行ガイドをご覧ください。
invalid_request
リクエストに問題がありました。これには次のような理由が考えられます。
リクエストの形式が正しくありません
リクエストに必須のパラメータが指定されていません
このリクエストで使用されている認証方法は Google でサポートされていません。OAuth 統合で推奨される統合方法が使用されていることを確認する
ステップ 4: OAuth 2.0 サーバー レスポンスを処理する 重要:
サーバーで OAuth 2.0 レスポンスを処理する前に、Google から受信した
state
が、承認リクエストで送信された state
と一致することを確認する必要があります。この検証により、リクエストを送信しているのが悪意のあるスクリプトではなくユーザーであることを確認できるため、CSRF 攻撃のリスクを軽減できます。 OAuth 2.0 サーバーは、リクエストで指定された URL を使用して、アプリケーションのアクセス リクエストに応答します。
ユーザーがアクセス リクエストを承認すると、レスポンスに認証コードが格納されます。ユーザーがリクエストを承認しないと、レスポンスにエラー メッセージが格納されます。ウェブサーバーに返される認証コードまたはエラー メッセージが、次のようにクエリ文字列に表示されます。
エラー レスポンス:
https://oauth2.example.com/auth?error=access_denied
認証コードのレスポンス:
重要: レスポンス エンドポイントが HTML ページをレンダリングする場合、そのページ上のすべてのリソースは URL 内の認証コードを参照できます。
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
スクリプトは URL を直接読み取ることができ、
Referer
HTTP ヘッダーの URL はページ上の任意またはすべてのリソースに送信される場合があります。そのページ上のすべてのリソース(特に、ソーシャル プラグインやアナリティクスなどのサードパーティ スクリプト)に認証情報を送信するかどうかを慎重に検討してください。この問題を回避するには、サーバーでまずリクエストを処理してから、レスポンス パラメータを含まない別の URL にリダイレクトすることをおすすめします。
OAuth 2.0 サーバー レスポンスの例
このフローをテストするには、次のサンプル URL をクリックします。この URL は、Google ドライブ内のファイルのメタデータを表示するための読み取り専用アクセス権と、Google カレンダーの予定を表示するための読み取り専用アクセス権をリクエストします。
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
access_type=offline&
include_granted_scopes=true&
state=state_parameter_passthrough_value&
redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
response_type=code&
client_id=client_id
OAuth 2.0 フローを完了すると、http://localhost/oauth2callback
にリダイレクトされます。ローカルマシンがそのアドレスでファイルを提供しない限り、404 NOT FOUND
エラーが発生する可能性があります。次のステップでは、ユーザーがアプリケーションにリダイレクトされたときに URI で返される情報について詳しく説明します。
ウェブサーバーは認証コードを受け取った後、認証コードをアクセス トークンと交換できます。
認可コードをアクセス トークンと交換するには、fetchAccessTokenWithAuthCode
メソッドを使用します。
$access_token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
Python コールバック ページで、google-auth
ライブラリを使用して認可サーバーのレスポンスを検証します。次に、flow.fetch_token
メソッドを使用して、そのレスポンスの認証コードをアクセス トークンと交換します。
state = flask.session['state']Ruby
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
'client_secret.json',
scopes=['https://www.googleapis.com/auth/youtube.force-ssl'],
state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)# Store the credentials in the session.
# ACTION ITEM for developers:
# Store user's access and refresh tokens in your data store if
# incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
'token': credentials.token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'granted_scopes': credentials.granted_scopes}
コールバック ページで、googleauth
ライブラリを使用して認可サーバーのレスポンスを検証します。authorizer.handle_auth_callback_deferred
メソッドを使用して認証コードを保存し、最初に認証をリクエストした URL にリダイレクトします。これにより、結果を一時的にユーザーのセッションに保存することで、コードの交換が延期されます。
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)Node.js
redirect target_url
認可コードをアクセス トークンと交換するには、getToken
メソッドを使用します。
const url = require('url');// Receive the callback from Google's OAuth 2.0 server.HTTP/REST
app.get('/oauth2callback', async (req, res) => {
let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied
console.log('Error:' + q.error);
} else if (q.state !== req.session.state) { //check state value
console.log('State mismatch. Possible CSRF attack');
res.end('State mismatch. Possible CSRF attack');
} else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code);
oauth2Client.setCredentials(tokens);
});
認証コードをアクセス トークンと交換するには、https://oauth2.googleapis.com/token
エンドポイントを呼び出して、次のパラメータを設定します。
フィールド
client_id
API Console
Credentials pageから取得したクライアント ID。
client_secret
API Console
Credentials pageから取得したクライアント シークレット。
code
最初のリクエストから返された認証コード。
grant_type
OAuth 2.0 仕様で定義されているように、このフィールドの値は
authorization_code
に設定する必要があります。redirect_uri
指定された
client_id
の API ConsoleCredentials page に、プロジェクトにリストされているリダイレクト URI のいずれか。
次のスニペットは、サンプル リクエストを示しています。
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencodedcode=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code
Google は、このリクエストに応答して、有効期間の短いアクセス トークンと更新トークンを含む JSON オブジェクトを返します。更新トークンは、アプリケーションが Google の認可サーバーの最初のリクエストで access_type
パラメータを offline
に設定した場合にのみ返されます。
レスポンスには、次のフィールドが含まれます。
フィールド
access_token
アプリケーションが Google API リクエストを承認するために送信するトークン。
expires_in
アクセス トークンの残り有効期間(秒単位)。
refresh_token
新しいアクセス トークンの取得に使用できるトークン。更新トークンは、ユーザーがアクセス権を取り消すまで有効です。繰り返しになりますが、このフィールドは、Google の認可サーバーの最初のリクエストで
access_type
パラメータを offline
に設定した場合にのみ、このレスポンスに存在します。scope
access_token
によって付与されるアクセス スコープ。スペース区切りの大文字と小文字を区別する文字列のリストとして表されます。token_type
返されるトークンのタイプ。現時点では、このフィールドの値は常に
Bearer
に設定されます。重要: アプリは、両方のトークンを、アプリの複数の呼び出し間でアクセスできる、安全で永続的な場所に保存する必要があります。更新トークンを使用すると、アプリは有効期限が切れたアクセス トークンの代わりに新しいアクセス トークンを取得できます。そのため、アプリケーションが更新トークンを失った場合、アプリケーションが新しい更新トークンを取得できるように、ユーザーは OAuth 2.0 同意フローを繰り返す必要があります。
次のスニペットは、サンプル レスポンスを示しています。
{注: アプリは、レスポンスに含まれる認識できないフィールドをすべて無視する必要があります。
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/youtube.force-ssl",
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}
エラー
認証コードをアクセス トークンと交換するときに、想定されるレスポンスではなく、次のエラーが発生することがあります。一般的なエラーコードと推奨される解決策を以下に示します。
invalid_grant
指定された認証コードが無効であるか、形式が正しくありません。OAuth プロセスを再起動して新しいコードをリクエストし、ユーザーに再度同意を求めます。
ステップ 6: ユーザーが付与したスコープを確認する
一度に複数のスコープをリクエストする場合、ユーザーがアプリがリクエストするすべてのスコープを許可しないことがあります。アプリは、ユーザーによって付与されたスコープを常に確認し、スコープが拒否された場合は関連する機能を無効にして対処する必要があります。詳細については、きめ細かい権限を処理する方法をご覧ください。
ユーザーが付与したスコープを確認するには、getGrantedScope()
メソッドを使用します。
// Space-separated string of granted scopes if it exists, otherwise null.Python
$granted_scopes = $client->getOAuth2Service()->getGrantedScope();
返された credentials
オブジェクトには granted_scopes
プロパティがあります。これは、ユーザーがアプリに付与したスコープのリストです。
credentials = flow.credentials
flask.session['credentials'] = {
'token': credentials.token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'granted_scopes': credentials.granted_scopes}
Ruby
複数のスコープを一度にリクエストする場合は、credentials
オブジェクトの scope
プロパティで、どのスコープが付与されたかを確認します。
# User authorized the request. Now, check which scopes were granted.Node.js
if credentials.scope.include?(Google::Apis::YoutubeV3::AUTH_YOUTUBE_FORCE_SSL)
# User authorized permission to see, edit, and permanently delete the
# YouTube videos, ratings, comments and captions.
# Calling the APIs, etc
else
# User didn't authorize the permission.
# Update UX and application accordingly
end
複数のスコープを一度にリクエストする場合は、tokens
オブジェクトの scope
プロパティで、どのスコープが付与されたかを確認します。
// User authorized the request. Now, check which scopes were granted.HTTP/REST
if (tokens.scope.includes('https://www.googleapis.com/auth/youtube.force-ssl'))
{
// User authorized permission to see, edit, and permanently delete the
// YouTube videos, ratings, comments and captions.
// Calling the APIs, etc.
}
else
{
// User didn't authorize read-only Drive activity permission.
// Update UX and application accordingly
}
ユーザーがアプリケーションに特定のスコープへのアクセス権を付与しているかどうかを確認するには、アクセス トークン レスポンスの scope
フィールドを確認します。access_token によって付与されたアクセス権のスコープ。スペース区切りの大文字と小文字を区別する文字列のリストとして表されます。
たとえば、次のアクセス トークン レスポンスの例は、ユーザーがアプリに、ユーザーの YouTube 動画、評価、コメント、字幕の表示、編集、完全削除の権限を付与したことを示しています。
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/youtube.force-ssl",
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}
Google API を呼び出す
アクセス トークンを使用して Google API を呼び出す手順は次のとおりです。
アクセス トークンを新しい
Google\Client
オブジェクトに適用する必要がある場合(アクセス トークンをユーザー セッションに保存した場合など)は、setAccessToken
メソッドを使用します。$client->setAccessToken($access_token);
呼び出す API のサービス オブジェクトを作成します。サービス オブジェクトをビルドするには、呼び出す API のコンストラクタに承認済みの
Google\Client
オブジェクトを指定します。たとえば、YouTube Data API を呼び出すには、次のようになります。 $youtube = new Google_Service_YouTube($client);
サービス オブジェクトによって提供されるインターフェースを使用して、API サービスにリクエストを送信します。たとえば、承認済みユーザーの YouTube チャンネルに関するデータを取得するには:
$channel = $youtube->channels->listChannels('snippet', array('mine' => $mine));
Python
アクセス トークンを取得した後、アプリケーションはそのトークンを使用して、特定のユーザー アカウントまたはサービス アカウントに代わって API リクエストを承認できます。ユーザー固有の認可認証情報を使用して、呼び出す API のサービス オブジェクトを作成し、そのオブジェクトを使用して承認済みの API リクエストを行います。
呼び出す API のサービス オブジェクトを作成します。サービス オブジェクトを作成するには、API の名前とバージョン、ユーザー認証情報を指定して
googleapiclient.discovery
ライブラリの build
メソッドを呼び出します。たとえば、YouTube Data API バージョン 3 を呼び出すには、次のようにします。from googleapiclient.discovery import buildyoutube = build('youtube', 'v3', credentials=credentials)
サービス オブジェクトによって提供されるインターフェースを使用して、API サービスにリクエストを送信します。たとえば、承認済みユーザーの YouTube チャンネルに関するデータを取得するには:
channel = youtube.channels().list(mine=True, part='snippet').execute()
Ruby
アクセス トークンを取得した後、アプリケーションはそのトークンを使用して、特定のユーザー アカウントまたはサービス アカウントに代わって API リクエストを送信できます。ユーザー固有の認可認証情報を使用して、呼び出す API のサービス オブジェクトを作成し、そのオブジェクトを使用して承認済みの API リクエストを行います。
呼び出す API のサービス オブジェクトを作成します。たとえば、YouTube Data API のバージョン 3 を呼び出すには、次のようにします。
youtube = Google::Apis::YoutubeV3::YouTubeService.new
サービスに認証情報を設定します。
youtube.authorization = credentials
サービス オブジェクトによって提供されるインターフェースを使用して、API サービスにリクエストを送信します。たとえば、承認済みユーザーの YouTube チャンネルに関するデータを取得するには:
channel = youtube.list_channels(part, :mine => mine)
または、メソッドに options
パラメータを指定することで、メソッドごとに認可を提供することもできます。
channel = youtube.list_channels(part, :mine => mine, options: { authorization: auth_client })
Node.js
アクセス トークンを取得して OAuth2
オブジェクトに設定したら、そのオブジェクトを使用して Google API を呼び出します。アプリケーションは、そのトークンを使用して、特定のユーザー アカウントまたはサービス アカウントに代わって API リクエストを承認できます。呼び出す API のサービス オブジェクトを作成します。たとえば、次のコードは Google Drive API を使用して、ユーザーのドライブ内のファイル名を一覧表示します。
const { google } = require('googleapis');// Example of using YouTube API to list channels.HTTP/REST
var service = google.youtube('v3');
service.channels.list({
auth: oauth2Client,
part: 'snippet,contentDetails,statistics',
forUsername: 'GoogleDevelopers'
}, function (err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var channels = response.data.items;
if (channels.length == 0) {
console.log('No channel found.');
} else {
console.log('This channel\'s ID is %s. Its title is \'%s\', and ' +
'it has %s views.',
channels[0].id,
channels[0].snippet.title,
channels[0].statistics.viewCount);
}
});
アプリケーションがアクセス トークンを取得すると、API で必要なアクセス権が付与されている場合は、そのトークンを使用して特定のユーザー アカウントの代わりに Google API を呼び出すことができます。これを行うには、access_token
クエリ パラメータまたは Authorization
HTTP ヘッダー Bearer
値のいずれかを含めて、API へのリクエストにアクセス トークンを含めます。クエリ文字列はサーバーログに表示されるため、可能であれば HTTP ヘッダーを使用することをおすすめします。ほとんどの場合、クライアント ライブラリを使用して Google API の呼び出しを設定できます(YouTube Data API を呼び出す場合など)。
YouTube Data API は、複数の YouTube チャンネルを所有して管理している YouTube コンテンツ所有者(レコード レーベルや映画制作会社など)のサービス アカウントのみをサポートしています。
すべての Google API を試して、そのスコープを確認するには、OAuth 2.0 Playground をご覧ください。
HTTP GET の例Authorization: Bearer
HTTP ヘッダーを使用して
youtube.channels
エンドポイント(YouTube Data API)を呼び出すと、次のようになります。独自のアクセス トークンを指定する必要があります。
GET /youtube/v3/channels?part=snippet&mine=true HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token
以下は、access_token
クエリ文字列パラメータを使用して、認証済みユーザーの同じ API を呼び出すコードです。
GET https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true
curl
の例これらのコマンドは、curl
コマンドライン アプリケーションでテストできます。HTTP ヘッダー オプションを使用する例を次に示します(推奨)。
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true
または、クエリ文字列パラメータ オプションを使用します。
curl https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true
サンプルコードの全文
次の例は、ユーザーがユーザーの YouTube アカウントを管理するようにアプリケーションを認証して承認した後、ユーザーの YouTube チャンネルに関する情報を示す JSON 形式のオブジェクトを出力します。
この例を実行するには:
API Consoleで、リダイレクト URL のリストにローカルマシンの URL を追加します。たとえば、
http://localhost:8080
を追加します。新しいディレクトリを作成し、そのディレクトリに移動します。次に例を示します。
mkdir ~/php-oauth2-example
cd ~/php-oauth2-example
Composer を使用して PHP 用 Google API クライアント ライブラリをインストールします。
composer require google/apiclient:^2.15.0
次の内容の
index.php
ファイルと oauth2callback.php
ファイルを作成します。PHP の組み込みテスト ウェブサーバーを使用してサンプルを実行します。
php -S localhost:8080 ~/php-oauth2-example
index.php
<?phpoauth2callback.php
require_once __DIR__.'/vendor/autoload.php';session_start();$client = new Google\Client();
$client->setAuthConfig('client_secret.json');// User granted permission as an access token is in the session.
if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
{
$client->setAccessToken($_SESSION['access_token']);
$youtube = new Google_Service_YouTube($client);
$channel = $youtube->channels->listChannels('snippet', array('mine' => $mine));
echo json_encode($channel);
}
else
{
// Redirect users to outh2call.php which redirects users to Google OAuth 2.0
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>
<?phpPython
require_once __DIR__.'/vendor/autoload.php';session_start();$client = new Google\Client();// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfigFile('client_secret.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']);// Required, to set the scope value, call the addScope function.
$client->addScope(GOOGLE_SERVICE_YOUTUBE::YOUTUBE_FORCE_SSL);// Enable incremental authorization. Recommended as a best practice.
$client->setIncludeGrantedScopes(true);// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType("offline");// Generate a URL for authorization as it doesn't contain code and error
if (!isset($_GET['code']) && !isset($_GET['error']))
{
// Generate and set state value
$state = bin2hex(random_bytes(16));
$client->setState($state);
$_SESSION['state'] = $state; // Generate a url that asks permissions.
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
}// User authorized the request and authorization code is returned to exchange access and
// refresh tokens.
if (isset($_GET['code']))
{
// Check the state value
if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
die('State mismatch. Possible CSRF attack.');
} // Get access and refresh tokens (if access_type is offline)
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']); /** Save access and refresh token to the session variables.
* ACTION ITEM: In a production app, you likely want to save the
* refresh token in a secure persistent storage instead. */
$_SESSION['access_token'] = $token;
$_SESSION['refresh_token'] = $client->getRefreshToken();
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}// An error response e.g. error=access_denied
if (isset($_GET['error']))
{
echo "Error: ". $_GET['error'];
}
?>
この例では、Flask フレームワークを使用します。http://localhost:8080
でウェブ アプリケーションを実行し、OAuth 2.0 フローをテストできます。その URL にアクセスすると、次の 5 つのリンクが表示されます。
API リクエストをテストする: このリンクは、サンプル API リクエストの実行を試みるページを参照しています。必要に応じて、承認フローを開始します。成功すると、ページに API レスポンスが表示されます。
認可フローを直接テストする: このリンクは、認可フローにユーザーを誘導しようとするページを参照しています。アプリは、ユーザーに代わって承認済みの API リクエストを送信するための権限をリクエストします。
現在の認証情報を取り消す: このリンクは、ユーザーがアプリにすでに付与している権限を
取り消すページを参照しています。
Flask セッションの認証情報を消去: このリンクは、Flask セッションに保存されている認可認証情報を消去します。これにより、アプリに権限を付与したユーザーが新しいセッションで API リクエストを実行しようとした場合にどうなるかを確認できます。また、ユーザーがアプリに付与された権限を取り消し、アプリが取り消されたアクセス トークンを使用してリクエストの認可を試みた場合に、アプリが受け取る API レスポンスも確認できます。
注: このコードをローカルで実行するには、前提条件セクションの手順に沿って、
http://localhost:8080
を認証情報の有効なリダイレクト URI として設定し、認証情報の client_secret.json ファイルを作業ディレクトリにダウンロードする必要があります。# -*- coding: utf-8 -*-import osRuby
import flask
import requestsimport google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"# The OAuth 2.0 access scope allows for access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl']
API_SERVICE_NAME = 'youtube'
API_VERSION = 'v3'app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'@app.route('/')
def index():
return print_index_table()@app.route('/test')
def test_api_request():
if 'credentials' not in flask.session:
return flask.redirect('authorize') # Load credentials from the session.
credentials = google.oauth2.credentials.Credentials(
**flask.session['credentials']) youtube = googleapiclient.discovery.build(
API_SERVICE_NAME, API_VERSION, credentials=credentials) channel = youtube.channels().list(mine=True, part='snippet').execute() # Save credentials back to session in case access token was refreshed.
# ACTION ITEM: In a production app, you likely want to save these
# credentials in a persistent database instead.
flask.session['credentials'] = credentials_to_dict(credentials) return flask.jsonify(**channel)
@app.route('/authorize')
def authorize():
# Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES) # The URI created here must exactly match one of the authorized redirect URIs
# for the OAuth 2.0 client, which you configured in the API Console. If this
# value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
# error.
flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_url, state = flow.authorization_url(
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline',
# Enable incremental authorization. Recommended as a best practice.
include_granted_scopes='true') # Store the state so the callback can verify the auth server response.
flask.session['state'] = state return flask.redirect(authorization_url)@app.route('/oauth2callback')
def oauth2callback():
# Specify the state when creating the flow in the callback so that it can
# verified in the authorization server response.
state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True) # Use the authorization server's response to fetch the OAuth 2.0 tokens.
authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response) # Store credentials in the session.
# ACTION ITEM: In a production app, you likely want to save these
# credentials in a persistent database instead.
credentials = flow.credentials
flask.session['credentials'] = credentials_to_dict(credentials) return flask.redirect(flask.url_for('test_api_request'))
@app.route('/revoke')
def revoke():
if 'credentials' not in flask.session:
return ('You need to <a href="/authorize">authorize</a> before ' +
'testing the code to revoke credentials.') credentials = google.oauth2.credentials.Credentials(
**flask.session['credentials']) revoke = requests.post('https://oauth2.googleapis.com/revoke',
params={'token': credentials.token},
headers = {'content-type': 'application/x-www-form-urlencoded'}) status_code = getattr(revoke, 'status_code')
if status_code == 200:
return('Credentials successfully revoked.' + print_index_table())
else:
return('An error occurred.' + print_index_table())@app.route('/clear')
def clear_credentials():
if 'credentials' in flask.session:
del flask.session['credentials']
return ('Credentials have been cleared.<br><br>' +
print_index_table())def credentials_to_dict(credentials):
return {'token': credentials.token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'granted_scopes': credentials.granted_scopes}def print_index_table():
return ('<table>' +
'<tr><td><a href="/test">Test an API request</a></td>' +
'<td>Submit an API request and see a formatted JSON response. ' +
' Go through the authorization flow if there are no stored ' +
' credentials for the user.</td></tr>' +
'<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
'<td>Go directly to the authorization flow. If there are stored ' +
' credentials, you still might not be prompted to reauthorize ' +
' the application.</td></tr>' +
'<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
'<td>Revoke the access token associated with the current user ' +
' session. After revoking credentials, if you go to the test ' +
' page, you should see an <code>invalid_grant</code> error.' +
'</td></tr>' +
'<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
'<td>Clear the access token currently stored in the user session. ' +
' After clearing the token, if you <a href="/test">test the ' +
' API request</a> again, you should go back to the auth flow.' +
'</td></tr></table>')if __name__ == '__main__':
# When running locally, disable OAuthlib's HTTPs verification.
# ACTION ITEM for developers:
# When running in production *do not* leave this option enabled.
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # This disables the requested scopes and granted scopes check.
# If users only grant partial request, the warning would not be thrown.
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1' # Specify a hostname and port that are set as a valid redirect URI
# for your API project in the Google API Console.
app.run('localhost', 8080, debug=True)
この例では、Sinatra フレームワークを使用します。
require 'googleauth'Node.js
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'require 'google/apis/youtube_v3'require 'sinatra'configure do
enable :sessions # Required, call the from_file method to retrieve the client ID from a
# client_secret.json file.
set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json') # Required, scope value
# Access scopes for retrieving data about the user's YouTube channel.
scope = 'Google::Apis::YoutubeV3::AUTH_YOUTUBE_FORCE_SSL' # Required, Authorizers require a storage instance to manage long term persistence of
# access and refresh tokens.
set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) # Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
set :callback_uri, '/oauth2callback' # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
# from the client_secret.json file. To get these credentials for your application, visit
# https://console.cloud.google.com/apis/credentials.
set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope,
settings.token_store, callback_uri: settings.callback_uri)
endget '/' do
# NOTE: Assumes the user is already authenticated to the app
user_id = request.session['user_id'] # Fetch stored credentials for the user from the given request session.
# nil if none present
credentials = settings.authorizer.get_credentials(user_id, request) if credentials.nil?
# Generate a url that asks the user to authorize requested scope(s).
# Then, redirect user to the url.
redirect settings.authorizer.get_authorization_url(request: request)
end
# User authorized read-only YouTube Data API permission.
# Example of using YouTube Data API to list user's YouTube channel
youtube = Google::Apis::YoutubeV3::YouTubeService.new
channel = youtube.list_channels(part, :mine => mine, options: { authorization: auth_client })
"<pre>#{JSON.pretty_generate(channel.to_h)}</pre>"
end# Receive the callback from Google's OAuth 2.0 server.
get '/oauth2callback' do
# Handle the result of the oauth callback. Defers the exchange of the code by
# temporarily stashing the results in the user's session.
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
redirect target_url
end
この例を実行するには:
API Consoleで、ローカルマシンの URL をリダイレクト URL のリストに追加します。たとえば、
http://localhost
を追加します。メンテナンス LTS、アクティブ LTS、または Node.js の最新リリースがインストールされていることを確認します。
新しいディレクトリを作成し、そのディレクトリに移動します。次に例を示します。
mkdir ~/nodejs-oauth2-example
cd ~/nodejs-oauth2-example
npm を使用して、Node.js 用 Google API クライアント ライブラリをインストールします。
npm install googleapis
次の内容の
main.js
ファイルを作成します。サンプルを実行します。
node .\main.js
main.js
const http = require('http');HTTP/REST
const https = require('https');
const url = require('url');
const { google } = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');/**
* To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
* To get these credentials for your application, visit
* https://console.cloud.google.com/apis/credentials.
*/
const oauth2Client = new google.auth.OAuth2(
YOUR_CLIENT_ID,
YOUR_CLIENT_SECRET,
YOUR_REDIRECT_URL
);// Access scopes for YouTube API
const scopes = [
'https://www.googleapis.com/auth/youtube.force-ssl'
];/* Global variable that stores user credential in this code example.
* ACTION ITEM for developers:
* Store user's refresh token in your data store if
* incorporating this code into your real app.
* For more information on handling refresh tokens,
* see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
*/
let userCredential = null;async function main() {
const app = express(); app.use(session({
secret: 'your_secure_secret_key', // Replace with a strong secret
resave: false,
saveUninitialized: false,
})); // Example on redirecting user to Google's OAuth 2.0 server.
app.get('/', async (req, res) => {
// Generate a secure random state value.
const state = crypto.randomBytes(32).toString('hex');
// Store state in the session
req.session.state = state; // Generate a url that asks permissions for the Drive activity and Google Calendar scope
const authorizationUrl = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',
/** Pass in the scopes array defined above.
* Alternatively, if only one scope is needed, you can pass a scope URL as a string */
scope: scopes,
// Enable incremental authorization. Recommended as a best practice.
include_granted_scopes: true,
// Include the state parameter to reduce the risk of CSRF attacks.
state: state
}); res.redirect(authorizationUrl);
}); // Receive the callback from Google's OAuth 2.0 server.
app.get('/oauth2callback', async (req, res) => {
// Handle the OAuth 2.0 server response
let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied
console.log('Error:' + q.error);
} else if (q.state !== req.session.state) { //check state value
console.log('State mismatch. Possible CSRF attack');
res.end('State mismatch. Possible CSRF attack');
} else { // Get access and refresh tokens (if access_type is offline)
let { tokens } = await oauth2Client.getToken(q.code);
oauth2Client.setCredentials(tokens); /** Save credential to the global variable in case access token was refreshed.
* ACTION ITEM: In a production app, you likely want to save the refresh token
* in a secure persistent database instead. */
userCredential = tokens;
// Example of using YouTube API to list channels.
var service = google.youtube('v3');
service.channels.list({
auth: oauth2Client,
part: 'snippet,contentDetails,statistics',
forUsername: 'GoogleDevelopers'
}, function (err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var channels = response.data.items;
if (channels.length == 0) {
console.log('No channel found.');
} else {
console.log('This channel\'s ID is %s. Its title is \'%s\', and ' +
'it has %s views.',
channels[0].id,
channels[0].snippet.title,
channels[0].statistics.viewCount);
}
});
}
}); // Example on revoking a token
app.get('/revoke', async (req, res) => {
// Build the string for the POST request
let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token
let postOptions = {
host: 'oauth2.googleapis.com',
port: '443',
path: '/revoke',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
}; // Set up the request
const postReq = https.request(postOptions, function (res) {
res.setEncoding('utf8');
res.on('data', d => {
console.log('Response: ' + d);
});
}); postReq.on('error', error => {
console.log(error)
}); // Post the request with data
postReq.write(postData);
postReq.end();
});
const server = http.createServer(app);
server.listen(8080);
}
main().catch(console.error);
この Python の例では、Flask フレームワークと Requests ライブラリを使用して、OAuth 2.0 ウェブフローを説明します。このフローには、Python 用 Google API クライアント ライブラリを使用することをおすすめします。([Python] タブの例では、クライアント ライブラリを使用しています)。
import json
import flask
import requestsapp = flask.Flask(__name__)# To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit
# https://console.cloud.google.com/apis/credentials.
CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123' # Read from a file or environmental variable in a real app# Access scopes for YouTube API
SCOPE = 'https://www.googleapis.com/auth/youtube.force-ssl'# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
REDIRECT_URI = 'http://example.com/oauth2callback'@app.route('/')
def index():
if 'credentials' not in flask.session:
return flask.redirect(flask.url_for('oauth2callback')) credentials = json.loads(flask.session['credentials']) if credentials['expires_in'] <= 0:
return flask.redirect(flask.url_for('oauth2callback'))
else:
headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
req_uri = 'https://www.googleapis.com/youtube/v3/channels/list'
r = requests.get(req_uri, headers=headers)
return r.text @app.route('/oauth2callback')
def oauth2callback():
if 'code' not in flask.request.args:
state = str(uuid.uuid4())
flask.session['state'] = state
# Generate a url that asks permissions for the Drive activity
# and Google Calendar scope. Then, redirect user to the url.
auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
'&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
SCOPE, state)
return flask.redirect(auth_uri)
else:
if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
return 'State mismatch. Possible CSRF attack.', 400 auth_code = flask.request.args.get('code')
data = {'code': auth_code,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'grant_type': 'authorization_code'} # Exchange authorization code for access and refresh tokens (if access_type is offline)
r = requests.post('https://oauth2.googleapis.com/token', data=data)
flask.session['credentials'] = r.text
return flask.redirect(flask.url_for('index'))if __name__ == '__main__':
import uuid
app.secret_key = str(uuid.uuid4())
app.debug = False
app.run()
リダイレクト URI の検証ルール
デベロッパーがアプリケーションの安全性を維持できるように、Google はリダイレクト URI に次の検証ルールを適用します。リダイレクト URI は次のルールに準拠している必要があります。以下で説明するドメイン、ホスト、パス、クエリ、スキーム、ユーザー情報の定義については、RFC 3986 セクション 3 をご覧ください。
検証規則
スキーム
リダイレクト URI には、プレーン HTTP ではなく HTTPS スキームを使用する必要があります。ローカルホスト URI(localhost IP アドレス URI を含む)は、このルールの対象外です。
ホスト
ホストは未加工の IP アドレスにすることはできません。ローカルホストの IP アドレスは、このルールの対象外です。
ドメイン
ホストの TLD(トップレベル ドメイン)は、公開サフィックス リストに属している必要があります。
ホストドメインは
“googleusercontent.com”
にできません。リダイレクト URI には、アプリがドメインを所有している場合を除き、URL 短縮ドメイン(
goo.gl
など)を含めることはできません。さらに、短縮ドメインを所有するアプリがそのドメインにリダイレクトする場合、そのリダイレクト URI のパスには “/google-callback/”
が含まれているか、末尾が “/google-callback”
である必要があります。Userinfo
リダイレクト URI に userinfo サブコンポーネントを含めることはできません。
[Path]
リダイレクト URI には、“/..”
または “\..”
またはその URL エンコードで表されるパス トラバーサル(ディレクトリ バックトラッキング)を含めることはできません。
クエリ
リダイレクト URI にオープン リダイレクトを含めることはできません。
Fragment
リダイレクト URI にフラグメント コンポーネントを含めることはできません。
文字数
リダイレクト URI には、次のような特定の文字を含めることはできません。
ワイルドカード文字(
'*'
)印刷不可能な ASCII 文字
無効なパーセント エンコード(パーセント記号の後に 2 桁の 16 進数を続ける URL エンコード形式に従わないパーセント エンコード)
null 文字(エンコードされた NULL 文字、
%00
、%C0%80
)段階的な認可
OAuth 2.0 プロトコルでは、アプリはリソースへのアクセス権をリクエストします。リソースはスコープで識別されます。リソースが必要なときにリソースの承認をリクエストすることをおすすめします。この方法を可能にするため、Google の認可サーバーは段階的な認可をサポートしています。この機能を使用すると、必要に応じてスコープをリクエストできます。ユーザーが新しいスコープの権限を付与すると、認可コードが返されます。このコードは、ユーザーがプロジェクトに付与したすべてのスコープを含むトークンと交換できます。
たとえば、ユーザーが興味深い地域のイベントを特定できるアプリがあるとします。このアプリでは、ユーザーがイベントに関する動画を視聴したり、動画に評価を付けたり、動画を再生リストに追加したりできます。ユーザーは、このアプリを使用して Google カレンダーに予定を追加することもできます。
この場合、ログイン時に、アプリがスコープへのアクセスを必要とせず、リクエストしないことがあります。ただし、ユーザーが動画の評価、動画の再生リストへの追加、または他の YouTube アクションを実行しようとした場合、アプリは https://www.googleapis.com/auth/youtube.force-ssl
スコープへのアクセスをリクエストできます。同様に、ユーザーがカレンダー イベントを追加しようとした場合、アプリは https://www.googleapis.com/auth/calendar
スコープへのアクセスをリクエストできます。
増分認可を実装するには、アクセス トークンをリクエストする通常のフローを完了しますが、認可リクエストに以前に付与されたスコープが含まれていることを確認します。この方法では、アプリで複数のアクセス トークンを管理する必要がなくなります。
増分認可から取得したアクセス トークンには、次のルールが適用されます。
このトークンを使用して、新しい統合された認可にロールされた任意のスコープに応じたリソースにアクセスできます。
統合された承認の更新トークンを使用してアクセス トークンを取得すると、アクセス トークンは統合された承認を表し、レスポンスに含まれる任意の
scope
値に使用できます。統合された承認には、ユーザーが API プロジェクトに付与したすべてのスコープが含まれます。これは、付与が異なるクライアントからリクエストされた場合でも同様です。たとえば、ユーザーがアプリのデスクトップ クライアントを使用して 1 つのスコープへのアクセス権を付与し、その後、モバイル クライアントを介して同じアプリに別のスコープを付与した場合、統合された認可には両方のスコープが含まれます。
結合された認可を表すトークンを取り消すと、関連付けられたユーザーに代わってその認可のすべてのスコープへのアクセスが同時に取り消されます。
注意: 付与されたスコープを含めるように選択すると、ユーザーが以前に付与したスコープが認可リクエストに自動的に追加されます。レスポンスで返される可能性のあるすべてのスコープをリクエストする権限がアプリに現在付与されていない場合、警告ページまたはエラーページが表示されることがあります。詳しくは、未確認のアプリをご覧ください。
ステップ 1: 認可パラメータを設定するの言語固有のコードサンプルと、ステップ 2: Google の OAuth 2.0 サーバーにリダイレクトするの HTTP/REST リダイレクト URL のサンプルはすべて、増分認可を使用しています。以下のコードサンプルには、増分認可を使用するために追加する必要があるコードも示されています。
$client->setIncludeGrantedScopes(true);
Python Python では、include_granted_scopes
キーワード引数を true
に設定して、以前に付与されたスコープが認可リクエストに含まれるようにします。次の例に示すように、include_granted_scopes
が設定する唯一のキーワード引数ではない可能性があります。
authorization_url, state = flow.authorization_url(Ruby
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline',
# Enable incremental authorization. Recommended as a best practice.
include_granted_scopes='true')
auth_client.update!(Node.js
:additional_parameters => {"include_granted_scopes" => "true"}
)
const authorizationUrl = oauth2Client.generateAuthUrl({HTTP/REST
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',
/** Pass in the scopes array defined above.
* Alternatively, if only one scope is needed, you can pass a scope URL as a string */
scope: scopes,
// Enable incremental authorization. Recommended as a best practice.
include_granted_scopes: true
});
この例では、呼び出し元のアプリは、ユーザーがすでにアプリに付与している他のアクセス権に加えて、ユーザーの YouTube アナリティクス データを取得するためのアクセス権をリクエストします。
GET https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly&
access_type=offline&
state=security_token%3D138rk%3Btarget_url%3Dhttp...index&
redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
response_type=code&
client_id=client_id&
include_granted_scopes=true
Refreshing an access token (offline access)
Access tokens periodically expire and become invalid credentials for a related API request. You
can refresh an access token without prompting the user for permission (including when the user is
not present) if you requested offline access to the scopes associated with the token.
If you use a Google API Client Library, the client object refreshes
the access token as needed as long as you configure that object for offline access.
If you are not using a client library, you need to set the
access_type
HTTPquery parameter to
offline
when redirecting the user toGoogle's OAuth 2.0 server. In that case, Google's authorization server returns a
refresh token when you exchange an authorization
code for an access token. Then, if the access token expires (or at any other time), you
can use a refresh token to obtain a new access token.
Requesting offline access is a requirement for any application that needs to access a Google
API when the user is not present. For example, an app that performs backup services or
executes actions at predetermined times needs to be able to refresh its access token when the
user is not present. The default style of access is called online
.
Server-side web applications, installed applications, and devices all obtain refresh tokens
during the authorization process. Refresh tokens are not typically used in client-side
(JavaScript) web applications.
If your application needs offline access to a Google API, set the API client's access type to
offline
:
$client->setAccessType("offline");
ユーザーがリクエストされたスコープへのオフライン アクセスを許可すると、ユーザーがオフラインの場合でも、API クライアントを使用してユーザーに代わって Google API にアクセスできます。クライアント オブジェクトは、必要に応じてアクセス トークンを更新します。
PythonPython では、access_type
キーワード引数を offline
に設定して、権限を再度プロンプトすることなくアクセス トークンを更新できるようにします。次の例に示すように、access_type
が設定する唯一のキーワード引数である可能性はほとんどありません。
authorization_url, state = flow.authorization_url(
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline',
# Enable incremental authorization. Recommended as a best practice.
include_granted_scopes='true')
ユーザーがリクエストされたスコープへのオフライン アクセスを許可すると、ユーザーがオフラインの場合でも、API クライアントを使用してユーザーに代わって Google API にアクセスできます。クライアント オブジェクトは、必要に応じてアクセス トークンを更新します。
Rubyアプリケーションで Google API へのオフライン アクセスが必要な場合は、API クライアントのアクセスタイプを offline
に設定します。
auth_client.update!(
:additional_parameters => {"access_type" => "offline"}
)
ユーザーがリクエストされたスコープへのオフライン アクセスを許可すると、ユーザーがオフラインの場合でも、API クライアントを使用してユーザーに代わって Google API にアクセスできます。クライアント オブジェクトは、必要に応じてアクセス トークンを更新します。
Node.jsアプリケーションで Google API へのオフライン アクセスが必要な場合は、API クライアントのアクセスタイプを offline
に設定します。
const authorizationUrl = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',
/** Pass in the scopes array defined above.
* Alternatively, if only one scope is needed, you can pass a scope URL as a string */
scope: scopes,
// Enable incremental authorization. Recommended as a best practice.
include_granted_scopes: true
});
ユーザーがリクエストされたスコープへのオフライン アクセスを許可すると、ユーザーがオフラインの場合でも、API クライアントを使用してユーザーに代わって Google API にアクセスできます。クライアント オブジェクトは、必要に応じてアクセス トークンを更新します。
アクセス トークンは期限切れになります。このライブラリは、有効期限が切れそうになると、自動的に更新トークンを使用して新しいアクセス トークンを取得します。常に最新のトークンを保存する簡単な方法は、tokens イベントを使用することです。
oauth2Client.on('tokens', (tokens) => {
if (tokens.refresh_token) {
// store the refresh_token in your secure persistent database
console.log(tokens.refresh_token);
}
console.log(tokens.access_token);
});
このトークン イベントは最初の承認でのみ発生します。generateAuthUrl
メソッドを呼び出して更新トークンを受け取るときに、access_type
を offline
に設定する必要があります。更新トークンの受信に適切な制約を設けずに、アプリに必要な権限をすでに付与している場合は、新しい更新トークンを受け取るためにアプリケーションを再承認する必要があります。
後で refresh_token
を設定するには、setCredentials
メソッドを使用します。
oauth2Client.setCredentials({
refresh_token: `STORED_REFRESH_TOKEN`
});
クライアントが更新トークンを取得すると、次回の API 呼び出しでアクセス トークンが取得され、自動的に更新されます。
アクセス トークンを更新するには、アプリケーションが Google の認可サーバーに HTTPS POST
リクエストを送信します。このリクエストには、次のパラメータが含まれます。https://oauth2.googleapis.com/token
フィールド
client_id
API Consoleから取得したクライアント ID。
client_secret
API Consoleから取得したクライアント シークレット。
grant_type
OAuth 2.0 仕様で定義されているように、このフィールドの値は refresh_token
に設定する必要があります。
refresh_token
認証コード交換から返された更新トークン。
次のスニペットは、サンプル リクエストを示しています。
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencodedclient_id=your_client_id&
client_secret=your_client_secret&
refresh_token=refresh_token&
grant_type=refresh_token
ユーザーがアプリケーションに付与されたアクセス権を取り消していない限り、トークン サーバーは新しいアクセス トークンを含む JSON オブジェクトを返します。次のスニペットは、サンプル レスポンスを示しています。
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
"token_type": "Bearer"
}
発行される更新トークンの数には上限があります。クライアントとユーザーの組み合わせごとに 1 つ、すべてのクライアントのユーザーごとに 1 つです。更新トークンは長期ストレージに保存し、有効である限り引き続き使用する必要があります。アプリがリフレッシュ トークンを過度にリクエストすると、これらの上限に達することがあります。その場合、古いリフレッシュ トークンは機能しなくなります。
ユーザーがアプリに付与したアクセス権を取り消す場合もあります。ユーザーは、[
アカウント設定] にアクセスしてアクセス権を取り消すことができます。詳しくは、アカウントにアクセスできるサードパーティのサイトやアプリのサポート ドキュメントの「サイトやアプリのアクセス権を削除する」をご覧ください。
アプリが、付与されたアクセス権をプログラムで取り消すことも可能です。プログラムによる取り消しは、ユーザーが定期購入を解約したり、アプリを削除したり、アプリに必要な API リソースが大幅に変更されたりした場合に重要です。つまり、削除プロセスの一部として、アプリに以前付与された権限が確実に削除されるように API リクエストを含めることができます。
トークンをプログラムで取り消すには、revokeToken()
を呼び出します。
$client->revokeToken();
Python プログラムでトークンを取り消すには、トークンをパラメータとして含め、Content-Type
ヘッダーを設定して https://oauth2.googleapis.com/revoke
にリクエストを送信します。
requests.post('https://oauth2.googleapis.com/revoke',Ruby
params={'token': credentials.token},
headers = {'content-type': 'application/x-www-form-urlencoded'})
プログラムでトークンを取り消すには、oauth2.revoke
エンドポイントに HTTP リクエストを送信します。
uri = URI('https://oauth2.googleapis.com/revoke')
response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
トークンは、アクセス トークンまたは更新トークンです。トークンがアクセス トークンで、対応する更新トークンがある場合、更新トークンも取り消されます。
取り消しが正常に処理された場合、レスポンスのステータス コードは 200
です。エラー状態の場合、ステータス コード 400
がエラーコードとともに返されます。
プログラムでトークンを取り消すには、/revoke
エンドポイントに対して HTTPS POST リクエストを送信します。
const https = require('https');// Build the string for the POST request
let postData = "token=" + userCredential.access_token;// Options for POST request to Google's OAuth 2.0 server to revoke a token
let postOptions = {
host: 'oauth2.googleapis.com',
port: '443',
path: '/revoke',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};// Set up the request
const postReq = https.request(postOptions, function (res) {
res.setEncoding('utf8');
res.on('data', d => {
console.log('Response: ' + d);
});
});postReq.on('error', error => {
console.log(error)
});// Post the request with data
postReq.write(postData);
postReq.end();
token パラメータには、アクセス トークンまたは更新トークンを指定できます。トークンがアクセス トークンで、対応する更新トークンがある場合、更新トークンも取り消されます。
取り消しが正常に処理された場合、レスポンスのステータス コードは 200
です。エラー状態の場合、ステータス コード 400
がエラーコードとともに返されます。
プログラムでトークンを取り消すには、アプリが https://oauth2.googleapis.com/revoke
にリクエストを行い、トークンをパラメータとして含めます。
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
https://oauth2.googleapis.com/revoke?token={token}
トークンは、アクセス トークンまたは更新トークンです。トークンがアクセス トークンで、対応する更新トークンがある場合、更新トークンも取り消されます。
取り消しが正常に処理されると、レスポンスの HTTP ステータス コードは 200
になります。エラー状態の場合、エラーコードとともに HTTP ステータス コード 400
が返されます。
クロスアカウント保護機能の実装
ユーザーのアカウントを保護するために、Google のクロスアカウント保護サービスを利用したクロスアカウント保護を実装することもおすすめします。このサービスを使用すると、セキュリティ イベント通知を定期購読して、ユーザー アカウントの大きな変更に関する情報をアプリに提供できます。その後、イベントへの対応方法に応じて、この情報に基づいてアクションを実行できます。
Google のクロスアカウント保護サービスからアプリに送信されるイベントの種類には、次のものがあります。
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
https://schemas.openid.net/secevent/risc/event-type/account-disabled
クロスアカウント保護の実装方法と利用可能なイベントの一覧については、
クロスアカウント保護でユーザー アカウントを保護する
をご覧ください。
... <看更多>
サイド 英語 在 YOASOBI 1st English EP"E-SIDE" Cross Fade Movie (第一弾 ... 的推薦與評價
2021年11月12日(金)リリースYOASOBI第一弾 英語 版EP「E- SIDE 」https://orcd.co/e_side1. Into The Night (夜に駆ける English Ver.) ... <看更多>