Outlook OAuth 2.0 でハマった話
OAuth
http://oauth.net/2/ OAuth2.0の備忘録的まとめ
RESTful APIでは常識になっているOAuthですが、 今回、私はOutlookのOAuth認証にハマりました。(´・ω・`)
ことの始まり
Outlookのスケジュールを管理できるアプリ欲しいなという要望のもと、 「Cordovaで簡単にアプリ作っちゃおう!!」 という感じでスタートしました。 この時はまだ、OAuth認証で丸一日以上を費やすとは思ってなかった・・・。 今までにOAuthを使ったAPIを何度か扱ったことはありますが、アクセストークンが取れないということはなかったです。
なぜハマったのか
それは今まで、OAuthライブラリーに頼っていたから。 つまり、実際にどうやってaccess_tokenを取得するかを理解していなかった。 ここで、ライブラリーに頼ってばかりではダメだと痛感しました。 CordovaのOAuthライブラリには、Outlookに対応しているものがなかったので、自前でOAuth認証を実装する必要がありました。 https://github.com/nraboy/ng-cordova-oauth ↑にOutlook(Office365)用のOAuth認証の機能を実装して、プルリクを送っておきます。
実際にコードを見てましょう。
AngularJS 1.5.xで書いています。
... function oauthOutlook(client_id, client_secret, redirect_uri) { var deferred = $q.defer(); var browser = window.cordova.InAppBrowser.open('https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=' + client_id + '&redirect_uri=' + redirect_uri + '&response_type=code' + '&scope=openid+https%3A%2F%2Foutlook.office.com%2Fcalendars.read', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes'); browser.addEventListener('loadstart', function(e) { if((e.url).indexOf('code') != -1) { var requestToken = (e.url).split("code=")[1]; if(requestToken) { $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; // client_id : client_secret をBase64にエンコード $http.defaults.headers.post['Authorization'] = 'Basic ' + window.btoa(client_id + ':' + client_secret); $http({method: "post", url: "https://login.microsoftonline.com/common/oauth2/v2.0/token", data: "client_id=" + client_id + "&code=" + requestToken + "&redirect_uri=http://localhost/callback" + "&client_secret=" + client_secret + "&grant_type=authorization_code" + "&scope=" + "openid+https://outlook.office.com/calendars.read" }) .success(function(data) { deferred.resolve({ access_token: data.access_token}); console.log("access_token", data.access_token); }) .error(function(data, status) { deferred.reject("Problem authenticating"); }) .finally(function() { setTimeout(function() { browser.close(); }, 10); }); } } else { deferred.reject("please login"); } }); return deferred.promise; } ...
参考: Java プログラミングで実装する OAuth 2.0 クライアント: 第 2 回 クライアント・クレデンシャル・グラント