ユーザー認証は、ほとんどのWebアプリケーションの基本機能です。 この機能は、さまざまなプログラミング言語を使用して実装され、さまざまなリポジトリ(「ハードコード」、ファイル、データベース、LDAPなど)でサポートされています。
私の以前の出版物では、「 当分の間、次のWebアプリケーションの作成は、ユーザー認証用の独自のデータ構造の設計から始まることが多い 」という大胆なエラーを表現しました。 カットの下には、これらの実装のユーザーモデルの構造の比較があります。
それは見えるだろう
認証は、すべてのWeb開発者になじみのある機能です。 Userモデルの最も単純なデータ構造は次のようなものです。
- ユーザー名
- パスワード
データがデータベースに配置される場合、多くの場合、別の(通常は整数の)属性によって補完されます。
- id
さて、Web開発者が基本機能のさまざまな実装を提供しているものを見てみましょう(さまざまな構造を単一のビューに持ってきませんでしたが、本質は明らかです)。 免責事項:私はこれらのモジュールを「戦い」で使用しませんでした。私の仮定は問題のデータ構造に基づいています-これらは単なる私の仮定であり、それ以上ではありません。 モジュールの開発者がユーザーの自宅の住所をemailという名前のフィールドに入力すると、私の計算は間違いなく誤解を招きます。
Zend fw 2
考慮される最も単純なデータスキーム :
CREATE TABLE user ( user_id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, username VARCHAR(255) DEFAULT NULL UNIQUE, email VARCHAR(255) DEFAULT NULL UNIQUE, display_name VARCHAR(50) DEFAULT NULL, password VARCHAR(128) NOT NULL, state SMALLINT )
データベースに最低限必要なセット(id、ユーザー名、パスワード)、および「人」の識別子(email、display_name)、およびユーザーステータスコード(アクティブ、非アクティブ、...)。 電子メールによる値の一意性は、ユーザー名と電子メールの両方による認証の可能性を示唆しています。
ララヴェル
Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password', 60); $table->rememberToken(); $table->timestamps(); });
また、最も簡潔なデータスキームの 1つです。 ユーザー検索は電子メールで行われ、ユーザーモデルの属性の最小セットは、ユーザー名の属性(「名前」-表示名)によって補完されます。 「rememberToken()」は、特定のブラウザの認証を保存するためのサポートを追加する可能性が高くなります(認証フォームの「Remember me」チェックボックス)。 「timestamps()」は、おそらく個々のレコードの作成日と変更日を追加します(削除される可能性がありますが、状態、ステータスなどの状態属性がないため、そうではありません)
Symfony2
FriendsOfSymfony / FOSUserBundle
<?xml version="1.0" encoding="UTF-8"?> <doctrine-mapping ...> <mapped-superclass name="FOS\UserBundle\Model\User"> <field name="username" column="username" type="string" length="180" /> <field name="usernameCanonical" column="username_canonical" type="string" length="180" unique="true" /> <field name="email" column="email" type="string" length="180" /> <field name="emailCanonical" column="email_canonical" type="string" length="180" unique="true" /> <field name="enabled" column="enabled" type="boolean" /> <field name="salt" column="salt" type="string" nullable="true" /> <field name="password" column="password" type="string" /> <field name="lastLogin" column="last_login" type="datetime" nullable="true" /> <field name="confirmationToken" column="confirmation_token" type="string" length="180" unique="true" nullable="true" /> <field name="passwordRequestedAt" column="password_requested_at" type="datetime" nullable="true" /> <field name="roles" column="roles" type="array" /> </mapped-superclass> </doctrine-mapping>
FOSUserBundle のデータ構造には、ユーザーのパスワードのリセットと最後のユーザー認証の時間の節約をサポートする属性が追加で含まれています。
Yii 2
$this->createTable('{{%user}}', [ 'id' => $this->primaryKey(), 'username' => $this->string(25)->notNull(), 'email' => $this->string(255)->notNull(), 'password_hash' => $this->string(60)->notNull(), 'auth_key' => $this->string(32)->notNull(), 'confirmation_token' => $this->string(32)->null(), 'confirmation_sent_at' => $this->integer()->null(), 'confirmed_at' => $this->integer()->null(), 'unconfirmed_email' => $this->string(255)->null(), 'recovery_token' => $this->string(32)->null(), 'recovery_sent_at' => $this->integer()->null(), 'blocked_at' => $this->integer()->null(), 'registered_from' => $this->integer()->null(), 'logged_in_from' => $this->integer()->null(), 'logged_in_at' => $this->integer()->null(), 'created_at' => $this->integer()->notNull(), 'updated_at' => $this->integer()->notNull(), ], $this->tableOptions);
考慮される最も複雑なデータ構造 。 独自の認証( "auth_key"-Remember-token?)に加えて、電子メールアドレス、パスワード回復、セッション制御( "logged_in_from"および "logged_in_at")、ユーザーデータの作成/変更の確認があります。
ジャンゴ
基本データモデルは、 AbstractBaseUserとAbstractUserの 2つのクラスで構成されています。
class AbstractBaseUser(models.Model): password = models.CharField(_('password'), max_length=128) last_login = models.DateTimeField(_('last login'), blank=True, null=True) class AbstractUser(AbstractBaseUser, PermissionsMixin): ... username = models.CharField(_('username'), max_length=150, unique=True, ...) first_name = models.CharField(_('first name'), max_length=30, blank=True) last_name = models.CharField(_('last name'), max_length=150, blank=True) email = models.EmailField(_('email address'), blank=True) is_staff = models.BooleanField(_('staff status'), default=False, ...) is_active = models.BooleanField(_('active'), default=True, ...) date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
最小限のスキームでも十分ですが、2つのクラスに「広がっています」。 興味深いものから-属性「is_staff」、Webアプリケーションの管理パネルへのユーザーアクセスのフラグ。
ループバック
非常に最小限のデータ構造 :
{ "name": "User", "properties": { "realm": { "type": "string" }, "username": { "type": "string" }, "password": { "type": "string", "required": true }, "email": { "type": "string", "required": true }, "emailVerified": "boolean", "verificationToken": "string" }, ... }
ユーザーの電子メールの検証をサポートし、追加の属性realm
を導入します。これにより、ユーザーを「ドメイン」に分割できます(これはマルチテナントアーキテクチャ、 SaaSプラットフォームに関連すると思います )。
春
データ構造も最小限です。
private String password; private final String username; private final Set<GrantedAuthority> authorities; private final boolean accountNonExpired; private final boolean accountNonLocked; private final boolean credentialsNonExpired; private final boolean enabled;
一連のユーザー権利とアカウントステータスフラグで展開します。
まとめ
ユーザー認証用の既成のデータ構造は、フレームワーク/フレームワークレベル(ループバック、Django、Spring)と個々のモジュールのレベル(ZF-Commons / ZfcUser、php-soft / laravel-users、FriendsOfSymfony / FOSUserBundle、dektrium /の両方に存在しますyii2-user)それぞれのフレームワーク。 一般化されたデータ構造はありません-各フレームワーク/モジュールは、独自の美しさの概念からはじかれています。 通常、フレームは汎用性が高いため、モジュールよりも属性が少ない構造を使用します。 ただし、最初は、代替認証スキームを実装できるサードパーティモジュールの基本構造を拡張する可能性を提供します。
最後に、「 ユーザー認証用の独自のデータ構造を設計する 」 ことについて、私の誤acyがどれほどあったかを知りたいと思います。