假设您的用户使用的网站是用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模型
接下来,我们需要确保模型将访问正确的数据库。 为此,请在项目中添加一个路由器,以查询不同的数据库 ,这会将请求从JoomlaUser模型重定向到其本机数据库。
在项目的主文件夹中创建文件“ db_routers.py”(在“ settings.py”所在的位置):
在settings.py
注册一个新路由器:
现在您可以从旧数据库中获得一个帐户。
启动Django终端并尝试拉取现有用户: 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
现在,您可以创建一个Django后端,以授权来自Joomla项目的用户。
阅读如何修改Django授权系统
在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网站的用户现在可以在新网站/应用程序上使用其凭据。
作为通过新界面进行的活动用户的授权,会将活动用户一张一张地复制到新数据库中。
或者,您可能不想将用户实体从旧系统复制到新系统。
在这种情况下, 这里是指向文章的链接,该文章描述了如何在Django (上述的JoomlaUser模型) 中用您自己的默认用户模型替换默认用户模型 。
是否转移用户的最终决定是基于新项目和旧项目之间的关系而做出的。 例如,新用户的注册将在哪里进行,哪个站点/应用程序将是主要站点,等等。
测试和文件
现在,请添加有关新代码的适当测试和文档。 该解决方案的逻辑与Django体系结构紧密相关,并且不是很明显,因此,如果您现在不执行测试/文档,将来对该项目的支持将变得更加复杂。