Google OAuth認証でボタン配置方法(安定版)

2022年12月9日

HTML Javascript セキュリティ テクノロジー プログラミング

eyecatch 先日紹介した、GoogleOAuthの現時点での最新記述方法ですが、なんとGoogleの内部仕様での不具合を発見してしまいました。 そんな不具合を残したままのシステム導入なんて、絶対に許されません。 ということで、その不具合を解消するためのリカバリー案として、確実に安定したログイン認証が出来る方法を書いておきます。

問題点があるので、モーダルウィンドウは使わない方が良い

先日のGoogleOAuth認証では、次のようなモーダルウィンドウが立ち上がって、ユーザーが持っているGoogleアカウントの一覧が表示されるような便利な状態でしたが、 この時に、モーダルウィンドウのcloseボタンを押すと、そのページではもう二度と同じモーダルウィンドウが立ち上がらなくなります。(画面をリロードしても立ち上がりません) いろいろ調べてみた所、このモーダルウィンドウを閉じた時に、cookie情報に、ユーザーがログインを拒絶して「二度と立ち上がってくれるなフラグ」という情報が書き込まれていました。 この場合の対応策としては、その対象のcookie情報(s_state)をdeleteしてあげると、元通りモーダルウィンドウが表示されるようになります。 でも、こんな操作通常ユーザーではやることが出来ないし、そもそもコレ不具合レベルの仕様ですから。 何故なら、cancel_on_tap_outsideというフラグをtrueでセットした場合、モーダルウィンドウの外側をクリックしたら、ウィンドウが閉じるという設定なんですが、この場合はcookieには何も書き込まれずに、何度もモーダルウィンドウが立ち上がる事ができます。 明らかに問題なので、もはやこのモーダルウィンドウを使わない方がいいというのが今回の結論です。

リカバリー案

では、いったいどうすれば良いのかと言うと、こうしたログインリストを表示するためのボタン表示をする機能があり、それを使うのが良さそうです。 こんなボタンです。他のサイトでよく見ますよね。 これまでは、自分のサイト内でのリンクをクリックしたらGoogleの処理をさせていたんですが、そのリンクをボタンにして設置すればよかったんですね。

ソース

この設置は次のように記述します。 <script src="https://accounts.google.com/gsi/client" async defer></script> <div id='google_login'></div> <script> window.onload = ()=>{ google.accounts.id.initialize({ client_id : '804503220905-iav9l316ldg3e7f9ijeos4kf597ij9ec.apps.googleusercontent.com', prompt_parent_id : 'google_login', style : 'position:static;', auto_prompt : true, auto_select : true, cancel_on_tap_outside : true, callback : logined_callback, }) google.accounts.id.renderButton( document.getElementById('google_login'),{} ) } function logined_callback(e){ const data = jwt_decode(e.credential) console.log(`ID: ${data.sub}`); console.log(`Full Name: ${data.name}`); console.log(`Given Name: ${data.given_name}`); console.log(`Family Name: ${data.family_name}`); console.log(`Image URL: ${data.picture}`); console.log(`Email: ${data.email}`); } function jwt_decode(jwt){ const base64Url = jwt.split('.')[1] const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/') const str1 = atob(base64) const str2 = escape(str1) const str3 = decodeURIComponent(str2) return JSON.parse(str3) } </script> これでボタンが表示されるだけですが、それをクリックすると、ポップアップウィンドウ(または別タブ)で、アカウントリスト表示がされて、ログインされた場合は、callbackが返ってきます。 閉じるボタンなどの心配もなく、cookieも安定しています。

あとがき

こうして手軽にログイン実装ができたら、それを保持して、認証後の処理を進めることができるので、本当にシステム構築が楽になります。 注意点としては、こうしたAPIログインは、ユーザー管理などは全てGoogleに任せられるんですが、アクセス数が爆発してしまうようなサービスを構築する場合は、やっぱり独自の認証をするシステムをくまないと行けないですね。 ちなみに、他にもFacebook , Twitter , github , などがよく使われているようですが、今回は最もポピュラーなgoogleのapiに限定してみましたが、他のサービス連携も考えたほうがいいのだろうか? それはそのサイトのコンテンツによって考えたほうがいいかもですね。 とりあえず、安定運用できるようになって、安心安心!

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。