Digamos que o site usado por seus usuários seja escrito em Joomla, mas para criar um novo produto para o seu público, você escolheu o pacote Python / Django.
Como resultado, você precisa usar contas de usuário do banco de dados Joomla no Django.
O problema, no entanto, é que o Joomla e o Django usam algoritmos diferentes de hash de senha, então apenas copiar as contas falha.
Depois de ler a documentação do Django, sobrecarregar a pilha e passar algum tempo, obtive a solução descrita abaixo, que usa as práticas de desenvolvimento recomendadas para o Django ao máximo.
Advertências
Essa solução arquitetônica pode não ser sua, veja a discussão nos comentários .
Para entender o que acontece nos exemplos abaixo, você deve ter algum entendimento da arquitetura do Django.
Eu também presumo que você sabe como implantar um projeto Django, então não estou descrevendo esse processo.
O código é copiado de um projeto em funcionamento, mas será fácil se ajustar ao seu projeto com um mínimo de alterações.
Provavelmente, na próxima versão principal do Django, esse código pode quebrar, no entanto, o princípio da solução permanecerá o mesmo.
Neste guia, não descrevo o front end do sistema de autorização, pois:
- qual front-end você dependerá das necessidades do seu projeto (pode até ser um terminal da API Json, por exemplo)
- esta informação já está descrita nos tutoriais oficiais do Django e em vários artigos para iniciantes
Algoritmo
- conectar o banco de dados Joomla (DB) ao projeto Django
- crie um modelo JoomlaUser representando um usuário do banco de dados Joomla
- escreva uma função
check_joomla_password()
que verifique se a senha digitada corresponde à senha original do usuário. - adicione um novo backend de autorização "Joomla Auth Backend" ao projeto, que, ao autorizar o cliente no Django, obterá a conta do usuário no banco de dados Joomla
1. Conexão ao banco de dados Joomla:
Se necessário, no mesmo arquivo com as configurações do projeto, você pode ativar o log de consultas do banco de dados:
2. crie um modelo JoomlaUser
- Leia como um modelo Django pode usar um banco de dados existente
- Pense em onde colocar o novo JoomlaUser.
No meu projeto, criei um aplicativo chamado "users" ( manage.py startapp users
). Ele conterá o back-end de autorização e o modelo de usuário do Joomla. - gere o modelo automaticamente usando o inspectdb:
python manage.py inspectdb live_users --database="joomla_db"
joomla_db - o nome do banco de dados que você especificou em settings.py/DATABASES
;
live_users - nome da tabela com contas.
adicione seu modelo a 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)
Em seguida, precisamos garantir que o modelo acesse o banco de dados correto. Para fazer isso, adicione ao projeto um roteador para consultas a diferentes bancos de dados , que redirecionará solicitações do modelo JoomlaUser para seu banco de dados nativo.
Crie o arquivo "db_routers.py" na pasta principal do projeto (no mesmo local em que seu "settings.py" está):
registre um novo roteador em settings.py
:
Agora você pode obter uma conta do banco de dados antigo.
Inicie um terminal do Django e tente puxar um usuário existente: python manage.py shell
>>> from users.models import JoomlaUser >>> print(JoomlaUser.objects.get(username='someuser')) JoomlaUser object (someusername) >>>
Se tudo funcionar (você vê o usuário), vá para a próxima etapa. Caso contrário, observe a saída de erro e corrija as configurações.
3. Verifique a senha da conta Joomla
O Joomla não armazena senhas de usuários, mas seu hash, por exemplo
$2y$10$aoZ4/bA7pe.QvjTU0R5.IeFGYrGag/THGvgKpoTk6bTz6XNkY0F2e
A partir do Joomla v3.2, as senhas dos usuários são criptografadas usando o algoritmo BLOWFISH .
Então eu baixei o código python com este algoritmo:
pip install bcrypt echo bcrypt >> requirements.txt
E criou uma função para verificar senhas no 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
Atenção! As versões do Joomla inferiores a 3.2 usam um método de hash diferente (md5 + salt), portanto esta função não funciona. Nesse caso, leia
discussão no Stackoverflow e crie uma função de verificação de hash que se parece com isso:
Infelizmente, eu não tenho uma base de usuários da versão antiga do Joomla em mãos, então não posso testar esse recurso para você.
4. Autorização de usuário back-end Joomla
Agora você está pronto para criar um back-end do Django para autorizar usuários do projeto Joomla.
leia como modificar o sistema de autorização do Django
Registre um novo back-end (ainda não existente) em project/settings.py
:
AUTHENTICATION_BACKENDS = [
Crie um back-end de autorização de usuário do Joomla em users/backend.py
from django.contrib.auth.models import User from .models import JoomlaUser def check_joomla_password(password, hashed):
Sumário
Parabéns - agora os usuários do seu site Joomla existente podem usar suas credenciais em um novo site / aplicativo.
Como autorização de usuários ativos por meio da nova interface, eles serão copiados um a um no novo banco de dados.
Como alternativa, você pode não querer copiar entidades do usuário do sistema antigo para o novo.
Neste caso, aqui está um link para um artigo que descreve como substituir o modelo de usuário padrão no Django pelo seu (o modelo JoomlaUser descrito acima).
A decisão final, de transferir ou não usuários, é tomada com base no relacionamento em que os projetos novos e antigos serão. Por exemplo, onde será realizado o registro de novos usuários, qual site / aplicativo será o principal, etc.
Teste e documentação
Agora, adicione os testes e a documentação adequados que cobrem o novo código. A lógica desta solução está intimamente ligada à arquitetura do Django e não é muito óbvia; portanto, se você não fizer testes / documentação agora, o suporte ao projeto se tornará mais complicado no futuro.