ガイド

認証とは?ログイン、セッション、OAuthをわかりやすく解説

認証とは、アプリがユーザーが誰であるかを確かめる仕組みです。通常は、本人だけが知っていること(パスワード)、本人が持っているもの(スマートフォンやメールに届いたコード)、または信頼できる別のサービスによる本人確認(「Googleでサインイン」など)のいずれかを確認します。ユーザーの認証が済むと、アプリはセッションやトークンでそのユーザーを覚えておくので、ページを移動するたびにログインし直す必要がありません。認証されたユーザーに何を許可するかを決めるのは、認可と呼ばれる別のステップです。

AIでアプリを作るときに重要な理由

ログイン機能の追加は、AIビルダーに頼まれることの多い作業の一つであり、微妙に間違えやすいものでもあります。ログイン画面はシンプルに生成できます。難しいのは、その周りのすべてです。

  • パスワードは安全に保存されているか?
  • 非公開のすべてのページと、すべてのAPIエンドポイントが、本当に誰がアクセスしているかを確認しているか?
  • ログイン済みの顧客が、URLの数字を変えて、他の顧客のデータを見られてしまわないか?
  • パスワードを忘れた人には、何が起こるか?

アプリは、これらすべてに失敗していても、見た目は完璧に安全に見えることがあります。仕組みの各部分を理解しておけば、正しい質問をして、正しい点をテストできます。

身近なたとえ

ホテルにチェックインする場面を考えてみてください。

フロントでIDを見せます。これが認証で、あなたが誰であるかを証明することです。その後、フロントの係はカードキーを渡します。このカードがセッションです。滞在中は、もうIDを見せる必要はなく、カードをかざすだけです。

そのカードで開くのは、あなたの部屋、ジム、そしてあなたの階へのエレベーターです。ほかの宿泊客の部屋やスタッフの事務所は開きません。これが認可で、あなたの身元で何にアクセスできるかを決めます。カードをなくした場合、ホテルはフロントでそのカードを無効にできます。これがセッションの取り消しです。チェックアウトすると、カードは使えなくなります。これがログアウトや有効期限です。

「Googleでサインイン」は、ホテルが自分でIDを確認する代わりに、信頼できるパートナーから「この人は本人です」と書かれた手紙を受け取るようなものです。

主なログイン方法

方法仕組み長所短所
メールアドレス+パスワード利用者がパスワードを決め、アプリはそのハッシュを保存する馴染みがあり、外部に依存しないハッシュを安全に保存し、再設定も扱う必要がある
マジックリンク/ワンタイムコードアプリがメールでリンクやコードを送り、それでログインさせる漏えいや忘れるパスワードがないメール配信に依存し、ログインに少し時間がかかる
ソーシャルログイン(OAuth/OpenID Connect)Google、Apple、GitHubなどでサインインする利用者にとって速い。あなたがパスワードを保存しなくてよい各提供元ごとの設定が必要。その提供元のアカウントを持たない利用者には使えない
ホスト型の認証サービスClerk、Auth0、Supabase Authなどが、会員登録、ログイン、再設定を担当するあなたのセキュリティ対応の手間が減る規模が大きくなると月額料金がかかる。依存先が増える
多要素認証(MFA/2FA)最初の確認の後に、認証アプリのコードなど、もう一つの確認を行う不正に侵入されにくくなる少しだけ手間が増える

パスワードはどう保存すべきか

安全なアプリは、実際のパスワードを保存しません。代わりにハッシュを保存します。ハッシュとは、パスワードを固定長の文字列に変換する一方向の関数の出力です。ログインするとき、アプリは入力された値をハッシュ化し、保存されているハッシュと比較します。

次の2つの点によって、この仕組みは安全になります。

  • ソルト:ハッシュ化の前に、パスワードごとにランダムな値を加えます。そのため、同じパスワードの2人でもハッシュは異なり、事前に計算された対応表は役に立ちません。
  • パスワード用に作られた低速なアルゴリズム:Argon2、bcrypt、scryptなどです。MD5やSHA-256のような汎用のハッシュは、単独で使うには速すぎます。攻撃者は何十億回も推測を試せてしまいます。

ハッシュ化は暗号化とは違います。暗号化されたデータは鍵を使えば復号できますが、パスワードのハッシュは、元に戻せないように設計されています。

セッションとトークンの違い

ログインした後、アプリはリクエストのたびにあなたを認識する必要があります。よく使われる方法は2つあります。

セッション(Cookie)トークン(例:JWT)
ブラウザーが持つものCookieに入ったランダムなセッションIDユーザー情報と有効期限を含む、署名されたトークン
ログイン状態の保存場所サーバー上(データベースや保存領域)トークンそのものの中
全デバイスからのログアウト簡単。サーバー上のセッションを削除すればよい難しい。ブロックリストを持たない限り、期限切れまでトークンは有効なまま
典型的な用途従来型のウェブアプリAPI、モバイルアプリ、サービス同士の通信

Cookieについては、3つの設定が重要です。HttpOnly(ページ上のJavaScriptからCookieを読めない)、Secure(HTTPSでのみ送信される)、SameSite(他のサイトからのリクエストでの送信を制限する)です。トークンをブラウザーのlocalStorageに保存するのはよくある方法ですが、ページ上で動くどのスクリプトからも見えてしまいます。

OAuthと「Googleでサインイン」

OAuth 2.0は、委任された認可のための標準です。アプリは、あなたのGoogleパスワードを一度も見ることなく、別のサービス上のあなたのアカウントへの限定的なアクセスを得られます。たとえば、Googleカレンダーの予定を読むといったことです。あなたはGoogleに移動し、特定の権限(スコープと呼ばれます)を承認します。Googleは、その権限だけを持つトークンをアプリに渡します。

OAuth単体は、アクセスを許可するために設計されたもので、あなたが誰であるかを伝えるためのものではありません。OpenID Connect(OIDC)は、OAuth 2.0の上に、本人確認の機能を加えた層です。「Googleでサインイン」や「Appleでサインイン」はこれを使っています。設定するには、提供元にアプリを登録して、クライアントIDとクライアントシークレットを受け取ります。シークレットはサーバーに保管しておきます。

具体例:クライアント向けポータルのログイン

デザイン会社のクライアントが、自分のプロジェクトと請求書を見られるポータルを作っているとします。

  • 認証: クライアントは、メールアドレスとマジックリンクでログインします。管理する必要のあるパスワードはありません。会社のスタッフは、Google Workspaceのアカウントでログインします。
  • 役割: 各ユーザーには役割があり、client(クライアント)かstaff(スタッフ)です。
  • 認可のルール:
操作クライアントスタッフ
自社のプロジェクトを見るはいはい
他社のプロジェクトを見るいいえはい
プロジェクトにファイルをアップロードする自分のプロジェクトのみはい
請求書を支払い済みにするいいえはい
  • どこで強制するか: すべてのリクエストで、サーバー側で行います。サーバーはログインしているユーザーを確認し、project.company_id がそのユーザーの会社と一致するプロジェクトだけを返します。「支払い済みにする」ボタンを隠すだけでは不十分です。エンドポイント自体が拒否する必要があります。

主な用語

用語意味
認証(AuthN)誰かが誰であるかを確認すること。
認可(AuthZ)その人が何をしてよいかを決めること。
セッションリクエストをまたいで、アプリがログイン状態を覚えていること。
Cookieブラウザーが、リクエストのたびにサイトへ送り返す小さなデータ。
JWTJSON Web Token。ユーザーIDや有効期限などの情報を持つ、署名された小さなトークン。
役割・権限アクセスを決める admin や member などのラベル。
MFA/2FA認証アプリのコードなど、もう一つの証明を求めること。
SSOシングルサインオン。1回のログイン(多くは会社のアカウント)で多くのアプリを使えること。
401と403「あなたは誰ですか?」(未認証)と、「その操作はできません」(未認可)の違い。

よくあるミスと誤解

  • ページ上だけで権限を確認する。 ブラウザーがボタンを隠しても、APIが確認しなければ、誰でもAPIを直接呼び出せます。
  • URLにあるIDを信用する。 /invoices/1042 は、請求書1042がログイン中のユーザーのものかを確認する必要があります。
  • 暗号を自作する。 よく知られたライブラリやサービスを使ってください。AIに独自のハッシュ方式を考えさせないでください。
  • 弱いパスワード再設定。 再設定のリンクは1回限りで、すぐに期限切れになり、メールアドレスにアカウントがあるかどうかを明かさないようにすべきです。
  • 自分のアプリの利用者と、ビルダーのアカウントを混同する。 アプリの利用者は、あなたがアプリを作るために使っているツールのアカウントとは別のものです。
  • ログインに回数制限がない。 制限がないと、攻撃者はパスワードを際限なく試せてしまいます。

AIビルダーに頼むときの依頼例

  • 「[よく知られたライブラリやサービス]を使って、会員登録とログインを追加して。独自のパスワードハッシュは書かないで。」
  • 「パスワードはbcryptかArgon2でハッシュ化して保存して。」
  • 「セッションには、HttpOnlyとSecureのCookieを使って。」
  • 「役割として管理者と一般会員を追加して。すべてのエンドポイントと、それを呼び出せる役割を一覧にして。」
  • 「利用者は自分のレコードだけを閲覧・編集できるように、サーバー側で強制して。そのうえで、どう確認したかを見せて。」
  • 「パスワード再設定を追加して。リンクは1回限りで、1時間で期限切れになるようにして。」
  • 「ログインの試行回数を制限して。」

そのうえで、ご自身でもテストしてください。アカウントを2つ作り、一方でログインした状態で、もう一方のデータにアクセスできないかを試します。ログイン機能の追加方法とセキュリティのチェックリストもご覧ください。

Mythexでの認証

Mythexは、アプリの利用者向けに組み込みの認証製品を提供していません。アプローチを選ぶのはあなたです。プロジェクトのデータベースに保存するメールアドレスとパスワードの方式か、ホスト型サービスのSDKのどちらかを選び、エージェントに追加するよう頼んでください。提供元のキーはチャットではなく、プロジェクトの秘密情報に登録します。これは、Mythexそのもののサインイン方法とは別のものです。アプリにログインを追加するためのドキュメントのレシピ(アプリにログインを追加する)には、調整して使える開始用のプロンプトがあります。サーバー側の確認がどこにあるべきかについては、APIとはで説明しています。

よくある質問

認証と認可の違いは何ですか?

認証は、あなたが誰かを確かめることです。たとえばパスワードを照合します。認可は、誰かが分かった後に、その人が何をしてよいかを決めることです。たとえば、管理画面を見られるか、他の人の予約を編集できるかといったことです。アプリには両方が必要です。

OAuthとは何ですか?

OAuth 2.0は、アプリがパスワードを知ることなく、別のサービス上のあなたのアカウントへ限定的なアクセス権を得られるようにする標準です。「Googleでサインイン」はOAuth 2.0の上に作られた認証の層であるOpenID Connectを使っていて、アプリはGoogleからあなたが誰かの情報を受け取ります。

アプリはパスワードを保存すべきですか?

読める形で保存することは決してしてはいけません。メールアドレスとパスワードでログインする場合、パスワードはソルト付きのハッシュとして保存しなければなりません。しかも、Argon2やbcryptのように、パスワード用に設計された低速なアルゴリズムで作ったものにします。多くのアプリは、ホスト型の認証サービス、ソーシャルログイン、メールのマジックリンクを使うことで、この問題を避けています。

セッションとトークン、アプリではどちらを使うべきですか?

どちらも使えます。セッションは、ログインの状態をサーバーに保存し、ブラウザーにはCookieでランダムなIDを渡します。無効にするのが簡単です。JWTのようなトークンは、署名された情報を自分で持ち運びます。APIやモバイルのクライアントに向いていますが、期限が切れる前に取り消すのは難しくなります。一般的なウェブアプリでは、Cookieを使ったセッションが無難な選択です。

Mythex · Pricing · AIでなんでも作ろう · ウェブサイト・アプリのテンプレート · Mythexを比較 · AIアプリ開発用語集 · AIアプリ開発の無料ツール · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)