ユーザーが使用するサイトがJoomlaで記述されているとしましょう。ただし、視聴者向けの新しい製品を作成するには、Python / Djangoバンドルを選択しました。
そのため、DjangoのJoomlaデータベースのユーザーアカウントを使用する必要があります。
ただし、問題は、JoomlaとDjangoが異なるパスワードハッシュアルゴリズムを使用するため、アカウントのコピーだけが失敗することです。
Djangoのドキュメントを読み、スタックオーバーフローを起こし、しばらく時間を費やした後、以下に説明するソリューションを得ました。これは、Djangoの推奨開発プラクティスを最大限に活用しています。
警告
このアーキテクチャ上の解決策はあなたに合わないかもしれません。 コメントの議論を参照してください。
以下の例で何が起こるかを理解するには、Djangoアーキテクチャについてある程度理解している必要があります。
また、Djangoプロジェクトをデプロイする方法を知っていると想定しているため、このプロセスについては説明しません。
コードは作業中のドラフトからコピーされますが、最小限の変更でプロジェクトに簡単に調整できます。
おそらく、Djangoの次のメジャーバージョンでは、このコードが破損する可能性がありますが、ソリューションの原則は変わりません。
このガイドでは、承認システムのフロントエンドについては説明しません。
- どのフロントエンドを使用するかは、プロジェクトのニーズに依存します(たとえば、Json APIエンドポイントである場合もあります)
- この情報は、公式のDjangoチュートリアルとさまざまなスターター記事で既に説明されています
アルゴリズム
- Joomlaデータベース(DB)をDjangoプロジェクトに接続します
- Joomlaデータベースからユーザーを表すJoomlaUserモデルを作成します
- 入力したパスワードがユーザーの元のパスワードと一致することを確認する
check_joomla_password()
関数を作成します。 - 新しい認証バックエンド「Joomla Auth Backend」をプロジェクトに追加します。これは、Djangoでクライアントを認証するときに、Joomlaデータベースからユーザーアカウントを取得します
1. Joomlaデータベースへの接続:
必要に応じて、プロジェクト設定と同じファイルで、データベースクエリのログを有効にできます。
2. JoomlaUserモデルを作成する
- Djangoモデルが既存のデータベースをどのように使用できるかを読む
- 新しいJoomlaUserを配置する場所について考えます。
私のプロジェクトでは、「users」( manage.py startapp users
)というアプリケーションを作成しました。 承認バックエンドとJoomlaユーザーモデルが含まれます。 - inspectdbを使用してモデルを自動的に生成します。
python manage.py inspectdb live_users --database="joomla_db"
joomla_db-settings.py/DATABASESで指定したデータベースの名前。
live_users-アカウントを持つテーブルの名前。
モデルをusers/models.py
追加します:
class JoomlaUser(models.Model): """ Represents our customer from the legacy Joomla database. """ username = models.CharField(max_length=150, primary_key=True) email = models.CharField(max_length=100) password = models.CharField(max_length=100)
次に、モデルが正しいデータベースにアクセスすることを確認する必要があります。 これを行うには、 異なるデータベースへのクエリ用のルーターをプロジェクトに追加します。これにより、リクエストがJoomlaUserモデルからネイティブデータベースにリダイレクトされます。
プロジェクトのメインフォルダー( "settings.py"と同じ場所)にファイル "db_routers.py"を作成します。
settings.py
新しいルーターを登録しsettings.py
。
これで、古いデータベースからアカウントを取得できます。
Djangoターミナルを起動し、既存のユーザーをpython manage.py shell
みます: python manage.py shell
>>> from users.models import JoomlaUser >>> print(JoomlaUser.objects.get(username='someuser')) JoomlaUser object (someusername) >>>
すべてが機能する場合(ユーザーが表示されます)、次の手順に進みます。 それ以外の場合は、エラー出力を見て設定を修正します。
3. Joomlaアカウントのパスワードを確認する
Joomlaはユーザーパスワードを保存しませんが、たとえば、ハッシュ
$2y$10$aoZ4/bA7pe.QvjTU0R5.IeFGYrGag/THGvgKpoTk6bTz6XNkY0F2e
Joomla v3.2以降、ユーザーパスワードはBLOWFISHアルゴリズムを使用して暗号化されます。
だから私はこのアルゴリズムでPythonコードをダウンロードしました:
pip install bcrypt echo bcrypt >> requirements.txt
そしてusers/backend.py
パスワードをチェックする関数を作成しました:
def check_joomla_password(password, hashed): """ Check if password matches the hashed password, using same hashing method (Blowfish) as Joomla >= 3.2 If you get wrong results with this function, check that the Hash starts from prefix "$2y", otherwise it is probably not a blowfish hash :return: True/False """ import bcrypt if password is None: return False
注意! 3.2より前のJoomlaバージョンは異なるハッシュ方式(md5 + salt)を使用するため、この関数は機能しません。 この場合、読む
Stackoverflowに関する議論と、次のようなハッシュチェック関数の作成:
残念ながら、古いバージョンのJoomlaのユーザーベースは手元にないため、この機能をテストすることはできません。
4.バックエンドユーザー認証Joomla
これで、Joomlaプロジェクトからユーザーを承認するためのDjangoバックエンドを作成する準備が整いました。
Django認証システムの変更方法を読む
project/settings.py
新しいバックエンド(まだ存在しない)を登録しproject/settings.py
。
AUTHENTICATION_BACKENDS = [
users/backend.py
でJoomlaユーザー認証バックエンドを作成します
from django.contrib.auth.models import User from .models import JoomlaUser def check_joomla_password(password, hashed):
まとめ
おめでとうございます-既存のJoomlaサイトのユーザーは、新しいサイト/アプリケーションで資格情報を使用できるようになりました。
新しいインターフェイスを介したアクティブユーザーの承認として、ユーザーは1つずつ新しいデータベースにコピーされます。
または、ユーザーエンティティを古いシステムから新しいシステムにコピーしたくない場合があります。
この場合、 Djangoでデフォルトのユーザーモデルを独自のモデル(上記のJoomlaUserモデル) に置き換える方法を説明した記事へのリンクがあります 。
ユーザーを転送するかどうかの最終決定は、新しいプロジェクトと古いプロジェクトの関係に基づいて行われます。 たとえば、新しいユーザーの登録が行われる場所、メインのサイト/アプリケーションなど。
テストとドキュメント
次に、新しいコードを対象とした適切なテストとドキュメントを追加してください。 このソリューションのロジックはDjangoアーキテクチャと密接に関連しており、あまり明確ではないため、テスト/ドキュメントを今すぐ行わないと、プロジェクトのサポートは将来より複雑になります。