メインコンテンツへスキップ
見出し画像

個人サイトに"Googleでログイン"を実装してみた ~Python Flask x Googleログインで安全なユーザー管理を実現~

    こんにちはRcatです。
    最近よく見かける"Googleでログイン"ってありますよね。すごく便利なんですが、あれ個人でもできるのでしょうか?
    調べたところできそうなので、今回は最近ホストし始めたサイトに導入しながらやり方の解説をしようと思います。


    はじめに

    利用規約

    情報や作品の活用時は事前に利用規約をご確認ください。

    コメントについて

    利用規約のガイドラインを確認の上コメントしてください。
    則っていないコメントは削除します。


    概要

    Googleでログインを実装するってなに?

    最近いろんなサイトでユーザー登録をしなくても利用できる、Googleでログインのボタン見ませんか?

    画像
    最終的な自作サイトからスクショ

    今どきりんご狂信者でもなければ大抵の方は持っているのでは?
    いちいちユーザ登録しなくてもいいので楽ですよね。パスワードもいらないし。
    で、今回はこれを個人のサイトに実装してみようと思います。
    つまり私のRcat999サイトに登録せずともGoogleでログインできるようになるというわけです。

    実装するサイト

    私のRcat999サイトは、データの配布やメンバー向けAPIの提供を行うサイトです。
    なのでログインしないといけないんですが、これを導入すれば皆さんのアクセスのハードルがだいぶ下がるはず。何せ、昔からGoogleフォームの利用規約を強制している時点でGoogleアカウントあるはずなので。
    また、IDとパスワードを使う場合、管理がきちんとしてないと漏洩の恐れがあります。しかし、Googleでログインの場合はメアドだけで認証可能なため、安全性が格段に向上します。

    Googleでログインの仕組み

    まず最初に簡単にGoogleでログインの仕組みを解説しておきます。

    仕組み

    1. 目的のサイトにアクセスする

    2. Googleでログインを押すと、Googleの認証画面にリダイレクトする
      この画面はGoogleのサイトであり、目的のサイトではないのが特徴。
      ここでユーザー名やパスワードを入れてGoogleにログインしても、すべてが目的のサイトに渡されるわけではない。

    3. 認証結果をもって目的のサイトに帰ってくる

    4. 目的のサイトが認証結果を検証して分析する

      1. 検証結果が本当にGoogleから発行された正規データか確認

      2. 正しい場合、データを読み解いてメールアドレスや名前などの要求したアカウントデータを取得する

      3. 自サイトにアカウントを自動生成するなどしてログインさせる

    5. ログイン完了

    ざっとこんな感じです。
    ログイン側が気になるのは2,3あたりですかね。Googleでログイン画面で本当にログインしてしまっていいのか、少々心配ですが全く問題ありません。
    なにせその画面の内容は目的のサイトとは隔離されていて見られないのですから。

    そして3で検証結果をお持ち帰りします。なので、目的のサイトに対して一切ユーザー情報が渡ってません。
    4で初めてサイトに情報を開示します。この開示される情報ですが、2でリダイレクトするときに何の情報がいるのかを含めてリダイレクトされます。

    ちなみに私のサイトはメアドだけです。スコープに名前やそれ以外も含めれば取得できるようですが、無くても動くので最低限にしています。

    で、4で結果を検証します。クライアントが持ってきた認証が本物かわからないからですね。確認出来たらそのメアドを信用してログイン状態にさせるという感じです。

    Googleでログインを実装するのに必要なこと

    さて、前置きはこのくらいにして、さっさと実装しましょう。

    環境

    こちらでやっていきます。超軽量の超簡易です。

    • 言語
      Python

    • フレームワーク
      Flask

    サーバー側要素

    それでは早速サーバー側の方から実装していきましょう。
    Googleにログインを実装するにあたって必要なのは下記です。

    • ログインボタンを配置するページ
      これはまあ当たり前ですね。ページがなければログインできません。

    • コールバックURL
      これがこの認証の特徴です。上で説明したように認証情報を持ち帰ってくると言いましたが、それがここに当たります。

    画像

    また、上記機能系ページとは別に次の3ページが必要です。
    これらは全てGoogleでログインボタンを設置するにふさわしいサイトかどうかの判別に使われます。

    • 規約関連
      Googleでログイン画面でリンクとして表示する必要があります。
      ログインするサイトと同じサイトでホストされている必要があり、外部ページへのリンクは許可されていません。

      • 利用規約

      • プライバシーポリシー

    • トップページ
      このサイトの目的をトップページで語る必要があります

    ちなみにトップページはこれで通りました。
    最初はログインボタン1個しか表示されなかったので落とされたんですが、とりあえず書いてあれば大丈夫そうです。
    利用規約とプライバシーポリシーはアクセスする機会があれば見てみてください。この程度でも大丈夫みたいです。

    画像

    また、最終的に公開状態にするにはサイトがTLSで暗号化されている必要があります。つまり、httpsになっているということですね。
    ここが普通はハードルが高いんですが、私は最近こういうのを見つけたのでこちらで対応しました。
    ※テスト中は"localhost"のみhttp可能です。192.168.0.1とかもNG

    GCPプロジェクト

    Googleでログインはgcpの機能の一部です。こちらはGoogleが提供するクラウドサービスですね。私は普段からジェミニAPIとかを使うので既に持ってるんですが、ない方は作成しましょう。

    この中でWebアプリケーションとしてデプロイします。まあ、とりあえず認証サーバーをクラウドサービスに登録すると思っておけばいいでしょう。

    サーバーを準備する

    では、サーバー側のコードから紹介していきます。
    なお、Flaskの使い方についてはある程度理解している前提です。

    Flask側Googleログイン実装コード

    というわけで、くどくど語るよりコードを貼って横にコメント書いときます

    画像

    このコードはブループリントと言ってFlaskですが、1ファイルではなく複数ファイルに分けたものを使っています。
    ルーティングの書き方がちょっと違うのかと思うかもしれませんが、あまり気にしなくて大丈夫です。

    コードを見てわかる通り、実装は本当に簡単です。本当は情報の検証などが複雑なのですが、そういうのを自分でやると脆弱性になり得るのでやらないのが良いらしいです。
    ですので、検証をするとそこでログインしたユーザーの情報を手に入れることができます。

    あとはこの情報を使ってどうするかはあなた次第ということですね。
    私の場合はGoogleフォームに回答していただいたメールアドレスがホワイトリストとして同期されているので、そこと照らし合わせを行っています。
    普通のサイトはこういうことをせずに、すぐにアカウントを作ってサービスを提供してくれるんですが、私の場合は目的がそうではないのでこういう仕組みです。

    ※authlibの初期化などはここでは省きます。
    ソースコードはDLできるので、そちらでご確認ください。

    ログインボタンを配置する

    次にフロントエンドにログインボタンを配置します。
    リンクで上で作ったURLに飛ばせばOKです。何それ簡単すぎ。

    画像

    こちらが私が使っているログイン画面のコードの一部になります。
    Vue.jsのコンポーネントです。ほぼHTMLと思って大丈夫。
    下の方でコメントになっているのが、初期のテスト用に使っていたボタンです。本当にただのリンクで飛ばしているだけです。

    画像

    ではその上にあるなんか長ったらしいコードは何なのか?
    実はこれがGoogleでログインボタンです。

    これの生成方法ですが、下記の公式サイトから生成することができます。ガイドラインに適した形で出力されるので、こちらをそのまま使うのが良いでしょう。

    ただし、生成直後はbuttonタグで出てくるんですが、それだと面倒くさいのでAタグに変更してます。そのくらいですね。
    リンクを飛ばすだけなのにボタンタグを使うのは良くないので。

    なお、Bootstrapを導入している場合は、ちょっと気をつけた方が良さそうです。最初はボタンの形が崩れてしまいました。なので、さらに上位をdivタグで囲う対策をしています。

    GCPプロジェクトを用意する

    サーバー側の準備が整ったら、次はクラウドにプロジェクトを作成します
    こちらから公式のプラットフォームにアクセスできます。

    初回はプロジェクトがありませんので、新規作成しましょう。

    認証情報を作成する

    APIとサービス、認証情報から新規認証情報を作ります。

    画像

    OAuthクライアントID

    画像

    Webアプリケーションを選択して、承認済みのリダイレクトuriに先ほど作成したコールバックURLを入れます。
    すでに本番環境向けのhttpsがある場合はそれも入れてOKです。というか最終的に必要です。

    画像

    この画像では例としてローカルホストだけ入れてあります。

    完了したらクライアントのシークレットをダウンロードしておいてください。これはサーバー側が受け取った認証情報をチェックするのにGoogleにアクセスするために使います。
    JSON形式を選んでおきましょう。

    ちなみにこの認証情報どこで使うかという話なんですが、認証ライブラリの初期化で使います。こんな感じですね。
    私のテンプレートだと、.envファイルに記述するところがあります。

    画像

    せっかくなので、一番下の引数を解説しておきます。これがユーザーの情報をどこまで要求するかという部分になります。見ての通りメアドしかありません。
    欲しい人はここに名前とか生年月日とか入れてくんでしょうね。くれるのか知らないですけど。

    ブランディングを作成する

    次にこのWebアプリが何なのか説明を入力します。

    ブランディングのタブに移動しましょう。
    上から順にアプリの名前、サポートメール、ロゴを入力します。

    画像

    サポートメールが外部に公開されるのかわかりませんが、一応ユーザーが問い合わせをするのに使うらしい。
    私の場合は利用規約で"Discordに参加してね"ということにしているので、メインアカウントではなく、別のアカウントを作って設定しました。
    こうする場合は、管理者として新しく作ったユーザーをこのプロジェクトに参加させることで選択できるようになります。

    次にドメインですね。これは最終的な本番環境のURLになります。
    上から順にトップページ
    プライバシーポリシー
    利用規約になります。

    上でも解説しましたが、トップページにはこのサイトの目的が書いてある必要があります。
    プライバシーポリシーと利用規約はトップページと同じドメインで見られる必要があります。
    私の場合はnoteに書いていますが、それの要約とコピーをそれぞれ貼り付けることで対応しました。
    ちっちゃくnoteの方が優先されますとも書いてます。それでも通ったので大丈夫でしょう。

    ちなみにこの画面の内容は以下のように反映されます。

    画像

    アプリを公開する&試行錯誤日記

    一通り準備ができたら、まずはローカルホストでログインできるか試してみましょう。
    問題なく通ったら、次は本番環境の方にデプロイして自分のユーザーでログインできる方でします。テスト中でもプロジェクトに参加しているユーザーであればログインすることが可能です。

    httpsの方で動作を確認したら、公開を行います。

    画像

    公開ボタンを押して公開します。
    なんか出てきましたが、ドメインは一つですし、スコープはメアドだけなので問題なさそうですね。

    画像

    なんか出てきました。だめらしいです!!

    画像

    ブランディングに不備がある??

    画像

    なんかGoogleサーチに引っかからないのが原因のよう・・・
    そりゃまあ、個人運用のサイトでかつSPAなんだから、そう簡単に引っかかるわけないだろう。

    画像

    なので自分からURLを指定して探しに行ってもらいます。
    URLを入れると所有者の確認が出るので、自分に合った方法で認証します。
    私はHeadへのMeta追加ですね。SPAなので任意のファイル返せないし。

    さて・・・またエラーですか。
    ※上の方ではすでに説明していましたが、この時点ではまだトップページにはボタンしかありませんでした。

    画像

    トップのメニュー画面がボタンだけじゃだめですか。
    ようこそ的な感じに改造しないといけなさそう。

    というわけで、ログインボタンだけのページから、Rcatサイトとは?というセクションと、安全性についての記述を増やしました。

    画像

    通りました!!

    画像

    公開ボタンを押します。

    画像

    ログインしてみる

    では早速ログイン画面に入ってっと。
    下側のボタンを押します!
    今更気づいたけど、ファビコン入れ替えるの忘れた。まあいいや。

    画像

    ログインボタンを押してっと…
    お、でましたね!

    画像

    そしてトップ画面にログイン後の追加メニューが増えた状態で出ました。
    フォロワーでメンバーシップにも参加している方は、このフル表示状態になるはず。
    ならない場合は何かしら不具合がある…。

    画像

    まとめ

    今回はGoogleでログインを個人のオンプレサイトに導入してみました。
    こういうのって、結構ハイレベルで難しいのかなぁなんて思ってたのですが、難しいところはライブラリが良しなにしてくれますので、きちんと動作原理だけ理解しておけばそこまで難しいことではなさそう。
    まぁGoogleでログインを実装するぞという個人がどれだけいるのかわかりませんがw

    もしもやりたいという方はぜひ試してみてくださいね。


    本内容を使用した「Rcat999サイト」について

    この記事を見ればわかると思いますが、ただGoogleでログインを興味本位で実装したわけでなく、本気で運用しています。
    なので、Rcatサイトの概要及びGoogleでログインを行った結果、どんな情報がRcat999に渡されて保持され利用されるのかを書いておこうと思います。

    詳しいことは別記事にしますので、こちらからご確認ください。


    配布情報

    配布URL

    こちらの記事で公開しているテンプレートに追加実装していますので、アップデートという形を取ります。

    リンク集

    感想投稿フォーム

    コメントは公開で恥ずかしい!! Rcatだけに送りたい人向け

    Pythonのインストール方法

    LoggingBOTの導入方法

    ミニPCにLinuxをインストール


     
     
    モノづくりが趣味。 "売ってないなら自分で作ればいいじゃない"をコンセプトに、機械/電気/AI/プログラム/ネットワーク 全部やります。 記事執筆はAI不使用。 ご連絡や利用規約はプロフィール記事参照。

    あなたへのおすすめ