ApexからGoogle OAuthを使う
前回艱難辛苦の果てにApexからService Account認証でGoogle APIを使用することに成功したわけですが、Google APIのラッパーとしてService Account認証にしか対応していないのはどうかと思うので、通常のServer Flowにも対応することにします。
と言ってもVisualForceは昨日Hello worldだけは作れるようになりましたが、コントローラのコードの呼び出し方とか意味がわからないのであきらめました。なので作ったのは例によってApexクラスのAPIだけです。(^^;
★ Google Cloud Consoleの設定
Server Flowでの認証を行うためにはGoogle側にRedirectURIの設定が必要です。
アプリケーション自体は前回作成したものを使用すれば良いので、追加で必要な設定は
APIs & auth > Registered apps > アプリケーション名 > OAuth 2.0 Client ID
と展開してWEB ORIGINとREDIRECT URIを設定することだけです。
OAuth認証の受け口はVisualForceの画面になる(多分)ので、以下のような感じで自分の組織のVisualForceページのURLを指定します。
- WEB ORIGIN: https://c.na14.visual.force.com
- REDIRECT URI: https://c.na14.visual.force.com/apex/GoogleLogin
★GoogleOAuthクラスの使い方
ドキュメントとソースコードは以下です。
- https://developers.google.com/accounts/docs/OAuth2WebServer
- https://github.com/shunjikonishi/apex-google-api/blob/master/src/classes/GoogleOAuth.cls
やってることはドキュメントに書かれていることを素直にコードに落としているだけなので見ればすぐにわかると思います。
必須項目はコンストラクタで引数として渡すようにし、それ以外の項目は任意のプロパティとしています。(access_typeなど2値のプロパティはBoolean型のプロパティとしています。)
それぞれの項目の意味は以下。
client_id:
Google Cloud Consoleで作成したアプリケーションのCLIENT ID
secret:
Google Cloud Consoleで作成したアプリケーションのCLIENT SECRET
scope:
認可を求める機能のURI。空白区切りで複数設定可。
カレンダーの読み書きを実行したい場合はGoogleCalendarServiceで定数として定義されているSCOPE_READWRITEまたはSCOPE_READONLYを指定すれば良い。
redirect_uri:
Google Cloud Consoleで設定したREDIRECT URI
ここで指定したURLにVisualForceでcodeとaccess_tokenを交換するロジック(GoogleOAuth#authenticateメソッドの実行)を実装する。
state:
任意の文字列。
指定するとredirect_uriで指定したURLに戻ってくる時にクエリストリングとして「&state=xxxx」のように自分が設定した値がそのまま返ってくる。
例えばログイン後に表示したい画面を切り替えるなど開発者側で自由に意味を持たせることができる。
offline_access: (access_type=offline)
offline_accessを使用するかどうか。
offline_accessを有効にした場合、認証のレスポンスにrefresh_tokenが含まれるのでそれを利用してaccess_tokenの有効期限が切れた後でも、いつでもどこからでも何度でもAPIを実行可能になる。
force_approval_prompt: (approval_prompt=force)
Googleの認可確認画面を毎回表示するかどうか。
デフォルトでは表示しない(approval_prompt=auto)となっていて、すでに認可がある場合は確認画面をスキップする
login_hint:
ログインユーザーに関するヒント。
アプリ側からログインユーザーを指定するなどの使い方ができるらしい
□□□□
これらの項目を設定すればGoogleOAuth#getLoginUrlメソッドでGoogleの認証URLが返ってきます。
そのページでアプリを承認するとredirect_uriで指定したURLにクエリストリングでcodeが返ってくるので、それをGoogleOAuth#authenticateメソッドに渡せばaccess_tokenが取得できます。あとは取得したaccess_tokenをGoogleCalendarService#setAccessTokenメソッドに渡せばCalendarAPIを使用できるようになります。(READMEのサンプルがほぼ全てです。)
https://github.com/shunjikonishi/apex-google-api
★offline_accessについて
offline_accessを要求して取得したrefresh_tokenはユーザがそのアプリをRevokeするまで自由に何度でも使用することができます。(このライブラリではGoogleOAuth#refreshTokenメソッドにrefresh_tokenを渡すことでrefresh_tokenとaccess_tokenを交換します。)
最初に一度だけrefresh_tokenを取得しておけば、それを延々と使い続けることができるので実質的にはService Account認証の代替として使用することが可能です。
offline_accessにはもう一つService Account認証よりも優位な点があってそれはメールアドレスとして自分の好きなアドレスを使用できるという点です。
Service Account認証ではイベントの作成者欄に表示されたり、招待メールのFromに設定されるメールアドレスはGoogleが自動発行したアドレスになるんですが、このアドレスが「999999999999-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com」(文字数を実際のアドレスと揃えてみました。)みたいな形式だったりするので誰だよ!っとなることは目に見えています。(JWTでprnを指定することで変更できるようですが、権限の設定方法がよくわからず。。。というか機能していない気がします。(--)
この点offline_accessを使用する場合は自分で用意したアドレスを使用できるので、怪しさは軽減されます。(^^;
。。。
どうりでService Account認証に関する資料やブログが少ないわけだよ。。。
誰も使ってないんでしょうね!
コメント