YouTubeのAnalytics and Reporting APIを使うときにrefresh_tokenを使ってaccess_tokenを更新する方法
GoogleのAPIを使って、何かしらデータを取得したいとき。
たとえば、ユーザーがYouTubeに投稿した動画の統計情報を取得したい、なんてときが該当します。
OAuth認証を実行してユーザーから許可をもらい、取得したアクセストークンを設定してAPIを実行することになりますがこのアクセストークンには期限があります。
アクセストークンは有効期限が1時間と短めに設定されていて、期限が切れたらOAuthでユーザーから認可を得るための画面を表示させて、再度ユーザーから許可をもらわないといけません。
1時間ごとにユーザーから許可もらうのはユーザーとしても運営としても面倒だし嫌ですね。
しかし、リフレッシュトークンを使うと、この問題を解消することができます。
順を追って説明していきます。
YouTubeの場合のサンプルプログラムは以下に掲載されています。
Using OAuth 2.0 for Web Server Applications
とりあえず、こちらにもサンプルを転記。
require 'google/apis/youtube_analytics_v1'
require 'google/api_client/client_secrets'
require 'json'
require 'sinatra'
enable :sessions
set :session_secret, 'setme'
get '/' do
unless session.has_key?(:credentials)
redirect to('/oauth2callback')
end
client_opts = JSON.parse(session[:credentials])
auth_client = Signet::OAuth2::Client.new(client_opts)
youtube = Google::Apis::YoutubeAnalyticsV1::YouTubeAnalyticsService.new
report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views', options: { authorization: auth_client })
"<pre>#{JSON.pretty_generate(report.to_h)}</pre>"
end
get '/oauth2callback' do
client_secrets = Google::APIClient::ClientSecrets.load
auth_client = client_secrets.to_authorization
auth_client.update!(
:scope => 'https://www.googleapis.com/auth/yt-analytics.readonly',
:redirect_uri => url('/oauth2callback'))
if request['code'] == nil
auth_uri = auth_client.authorization_uri.to_s
redirect to(auth_uri)
else
auth_client.code = request['code']
auth_client.fetch_access_token!
auth_client.client_secret = nil
session[:credentials] = auth_client.to_json
redirect to('/')
end
end
リフレッシュトークンを使おう
アクセストークンは1時間しかもちませんが、回避方法があります。
リフレッシュトークンを使うと、ユーザーに改めて許可をもらうことなく、アクセストークンを再取得することが可能です。
このリフレッシュトークンは最初にアクセストークンを取得したときに一緒についてきます。
上記のサンプルコードはリフレッシュトークンを使うように書かれていないので、少し手を加えてリフレッシュトークンを使えるようにしてみましょう。
まず、get '/oauth2callback'
の初期化のところです。
以下のようにauth_client.update!
の引数に'access_type' => 'offline'
と設定しておきます。
こうすることで、アクセストークンを再取得するときにユーザーから許可を得なくても大丈夫になります。
client_secrets = Google::APIClient::ClientSecrets.load
auth_client = client_secrets.to_authorization
# additional_parametersのオプションを追加しておく
auth_client.update!(
:scope => 'https://www.googleapis.com/auth/yt-analytics.readonly',
:redirect_uri => url('/oauth2callback'),
:additional_parameters => {
'access_type' => 'offline' # offline accessを許容するように設定しておく
}
)
次にリフレッシュトークンを使うコードを足し込んでいきます。
get '/'
でYouTubeのAPIを実行していますが、APIを実行する前にauth_client
にAPIのクライアントシークレットを設定し、refresh!
メソッドを実行します。
このメソッドを実行した時点でリフレッシュトークンを使って、アクセストークンを再取得してくれます。
これにより、アクセストークンの期限が切れてもアクセストークンが更新されて再びAPIを実行することができます。
get '/' do
unless session.has_key?(:credentials)
redirect to('/oauth2callback')
end
client_opts = JSON.parse(session[:credentials])
auth_client = Signet::OAuth2::Client.new(client_opts)
# ここでclient_secretを設定しておく
auth_client.client_secret = ENV['YOURE_CLIENT_SECRET']
# これでrefresh_tokenを使って、access_tokenを再取得する
auth_client.refresh!
# そうすれば、APIを再び実行することができる
youtube = Google::Apis::YoutubeAnalyticsV1::YouTubeAnalyticsService.new
report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views', options: { authorization: auth_client })
"<pre>#{JSON.pretty_generate(report.to_h)}</pre>"
end
このrefresh!
メソッドは以下のソースコードにあるように、fetch_access_token!
の別名として定義されているだけですね。
fetch_access_token!
を使っても、リフレッシュトークンは使ってくれると思います。
この記事の環境情報
- Ruby 3.1.2
- googleauth 0.17.1
Rubyに関する他の記事を読む
- slimでtype='application/ld+json'のscriptタグを書く
- Slack APIによる自動メッセージでユーザーグループにメンションする方法
- RubyでUnixtimeからTimeオブジェクトを生成する
- gemインストール時にUndefined symbols for architecture arm64と出たときの対応
- RubyでUTCの時刻情報をJST基準に変換する
最近の記事を読む
- Flutterでcontextを使わずにlocale情報を取得する
- Cloud RunでIAPを有効にしようとしてハマったこと
- slimでtype='application/ld+json'のscriptタグを書く
- タグマネージャーでjsのloadイベントを発火させたいとき
- mysqlコマンドを実行してERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)と言われたら