Google > AppEngine > Java API で認証処理をする

前置き


地道な Get,Postの処理で認証を受けて、SpreadSheet の情報を取り出したりはできたものの、自前でClassをどんどん作って拡張させていく感じだったので、ライブラリつかいたひ、となって、そのためには、認証とかからこれを使ったほうが良いんじゃないか、ということで挑戦。ただ、Servletとしての説明が載った日本語のサイトがあんまりないので(GData以前はそれなりにある感じ)、いろいろ情報を見ながらトライ&エラーで作ってみた。

基本はここを参照したものの、初心者は四苦八苦。
Google API Client Libraries

流れ自体は通常の認証と変わらないものの、APIでいろいろやってくれる分、中身がわからないので、どこで何をしているのかわからん。
https://developers.google.com/identity/protocols/OAuth2

そして、作って、とりあえず使えそうな見通しがたったところで、
Google Identity Platform
こっちの情報をさんしょうすれば、JavaAPIとかいらんかったのか?とか思いながら、まだちゃんと読んでいない。

とりあえずいろいろ集めた情報から
サーブレットを使ったパターンとしては
  1. AbstractAppEngineAuthorizationCodeServlet.classを実装したクラスで、認証に必要な情報を載せて、リダイレクトさせる
    • GoogleAuthorizationCodeFlow を内部で作って、使用している。上記のクラスを実装しなくても、本来はこれだけあればいい?
    • 認証ページを表示させて、デフォルトで /oauth2callback にリダイレクトさせる。
    • codeをつけて、リダイレクトさせる。
  2. AbstractAppEngineAuthorizationCodeCallbackServlet.classを実装したクラスで、結果を受ける。
    • リダイレクトされたあとだから、イランと思ったら、ここでもGoogleAuthorizationCodeFlow を内部で作って処理していた。
    • 認証に成功すると Credential がもらえる。
    • この認証後に、どのページからでも使える?ように access token を Cookie に保存して、再利用することにした。他のやり方がまだわからない。

実装までの四苦八苦

事前準備

使うサイト(Web App)を登録する作業は、Java API を使おうが使うまいが同じ。ここで Client ID とか、Client Secret とかを登録、確認しておく。
また、リダイレクト先も登録。ここで登録したリダイレクト先と、この先のプログラム上で指定しているリダイレクト先が違うとエラーになる。何もしないと多分 /oauth2callback がプログラム内で使用されるので、とりあえずこれを指定した(そしてそういうプログラムを作った)ほうが早いのでは?

認証ページを表示させるところまで。

AbstractAppEngineAuthorizationCodeServlet.classを実装。デベロッパサイトに注意書きとサンプルコートが。

注意:ログインしているユーザがいないと getUserID() が NullPointerException を投げる。-> web.xml に次の記述がこんな感じの記述が必要。
 <security-constraint>
   <web-resource-collection>
     <web-resource-name>any</web-resource-name>
     <url-pattern>/*</url-pattern>
   </web-resource-collection>
   <auth-constraint>
     <role-name>*</role-name>
   </auth-constraint>
 </security-constraint>
role-nameの指定で、なんやかんやできるみたいだが。

このページのサンプルコードをそのまま使ったが、オーバーライドすべき initializeFlow 内での AuthorizationCodeFlowの生成で指定するGenericURLとかわからない。
しかしGoogleAuthorizationCodeFlowという拡張されたクラスがあって、こちらのBuilderクラスではGenericURLの指定はなく、代わりにClientID、ClientSecretの指定で済むので、こちらでインスタンスを作る。なお
  • setApprovalPrompt("auto")
  • setAccessType("offline")
も指定してbuild()

これで動かすとデータへのアクセス許可を聞くサイトへ飛んだ。

リダイレクト後(codeが発行された後の処理)

認証画面へのリダイレクトと同じように、コールバック用のサーブレットとしてAbstractAppEngineAuthorizationCodeCallbackServletを実装。
この中でもAuthorizationCodeFlowが出てくるが、やっぱりGoogleAuthorizationCodeFlowで実装。
このサーブレットでcodeを受け取ると、自動的に(flowがあるから?)access tokenとの交換をしてくれるらしい。オーバーライドする関数として
  • onSuccess
  • onError
があって、成功していればonSuccessが処理される。ここの引数としてcredentialがあるので、getAccessTokenでトークンを保存しておけば、しばらくはこれを使ってAPIにアクセスできる。ただ、私は保存の仕方がわからなかったので、Cookieに保管している。

access tokenを受け取った後、実際にAPIを動かす

今回の主目的はSheets API、Calendar API だったので、とりあえずSheets APIで確認。
GoogleCredential gc = new GoogleCredential.Builder().build();
とやるだけで、勝手にどこかに保管されたaccess tokenとか拾ってくれるか、と思ったが、そこまで優しくない。(GoogleCredential.getAccessToken()はnullだったので)Cookieからaccess tokenを取り出して、credentialにセットして
Sheets sheet = new Sheets.Builder(HTTP_TRANSPORT, [[JSON]]_FACTORY, gc).setApplicationName(APPLICATION_NAME).build();
でオブジェクト作って、叩いたら、データ取り出せた。サンプルは[[Google Sheets API
Java Quickstart>>https://developers.google.com/sheets/quickstart/java]]のmain内の部分。
最終更新:2016年10月16日 19:13