記事
最新の情報をお届けします
00:00:00
WEBサービスの認証機能とユーザー管理

まえふり

WEBサービスにしろ、モバイルアプリにしろ、ユーザー認証の仕組みを実装するケースはよくあります。組織管理やコンテンツへのアクセス権限の管理なども、ユーザー認証の方法を軸に考えることが大半です。以下では、ユーザー認証を実装する上で考えるポイントを簡単にではありますが整理してみました。

Sign up/in/out の実装

通常は、ブラウザのSession/Cookieの機構を使って管理するケースが多いとおもいます。ネイティブアプリでCookieの利用が微妙な場合は、サーバー側でトークンを発行し、クライアント側でそのトークンを保存しておき、リクエスト時にそのトークンでセッションを管理します。

APIの場合のアクセストークン

モバイルアプリの場合、サーバーサイドはJSONを返すだけの、APIサーバーになるケースがあります。その場合は、Session/Cookieを使って認証してもいいのですが、API呼び出し用のtokenを発行し、アプリにそのtokenを保存しておき(keychainなどに保存)、Request Header にセットするケースがあります。

ログイン管理のオプション

ログイン機構を作る場合は以下も実装することが多々あります。

  • user activation(メールでの本人確認)
  • reset password(パスワードを忘れた場合)
  • remember me(ログイン保持の期間延長)
  • session timeout(セッションタイムアウトの時間の設定)

Passwordの暗号化

サイト側の対策として、まずソルト(Salt)は必ず採用すべきです。ソルトというのは、ハッシュ値を計算する前にパスワードの前後に付け加える短い文字列です。

ソルト化ハッシュ = hash(パスワード + ソルト) ※注: +は連結演算子

ソルトによる効果は以下の通りです。

  • 同じパスワードを付けていても、ハッシュ値は異なるようにできる
  • ハッシュ値の元となる文字列を長くすることにより、レインボーテーブル探索を妨害する

これらの効果を得るために、ソルトには以下の要件が必要となります。

  • ユーザーごとに異なるソルトを使う
  • ある程度の長さ(20文字程度以上)を確保する

教科書などでは、ソルトに乱数を使っている実装をよく見かけますが、原理的には乱数である必要はありません。通常、ソルトはハッシュ値とともに保存するので、オフライン攻撃者にとってソルトは秘密情報ではありません。また、ある程度長さが確保できれば、ユーザーIDそのものをソルトにすることもできますが、ユーザーIDを後から変更できるサイトの場合は実装に工夫が必要になります。

本当は怖いパスワードの話:ハッシュとソルト、ストレッチングを正しく理解する - @IT

OAuthでのaccess_token取得

Facebook, Twitter, GitHub などでのOAuth認証を実装する場合がよくあります。大体の場合、callbackでaccess_tokenが返ってくるので、tokenをDBに保存し、外部サービスとの連携時にそのtokenを利用する。

二段階認証

最近は、二段階認証の実装が義務っぽい感じになっている印象があります。

Active DirectoryやGoogle Appsとの連携

法人向けのソフトウェアの場合は、Active DirectoryやGoogle Appsとの連携を想定する必要があります。

SMS認証

電話番号を入力してもらい、SMSでパスコード送信し本人確認する。

招待機能

Emailなどで招待を行える機能を実装するケースがよくあります。

審査フロー

会員登録時に本人確認以外に、審査をするケースがあります。例えば、決済代行サービスでは、登記簿のPDFを送信させるケースなどもあります。審査の段階などを確認できる画面の実装が必要になります。

ロール(Role)管理

ユーザーにRoleがある場合は、データとして管理します。ロールによって表示する画面が違う場合があります。例えば、クラウドソーシングサービスでは発注者と受注者で表示する画面が違います。その場合も、認証経路は同じにして、認証後にRoleをみて表示を切り替える場合があります。

プロフィール(Profile)管理

認証とは関係なく、取得する情報があります。また、マイページなどの場合は、公開の管理も必要です。

ログイン後の設定画面(Setting)

プロフィールデータの更新、パスワードの変更、メールアドレスの変更などを管理する必要があります。メールアドレスの変更などは、その都度で本人確認用のメールを送信する必要があります。