tl; dr - Come utilizzare una libreria lato Python come PassLib in password hash prima di inserirli in un DB MySQL con SQLAlchemy?SQLAlchemy & PassLib
Va bene, così ho sbattere la testa sulla mia scrivania per un giorno o due cercando di capire questo fuori, così qui va:
Sto scrivendo un'applicazione web utilizzando Piramide/SQLAlchemy e Sto cercando di interfacciarmi con la tabella Utenti del mio database MySQL.
In definitiva, voglio fare qualcosa di simile al seguente:
Confronta una password per l'hash:
if user1.password == 'supersecret'
Inserire una nuova password:
user2.password = 'supersecret'
mi piacerebbe essere in grado di usare PassLib per cancellare le mie password prima che entrino nel database, e non sono proprio un fan dell'uso della funzione incorporata di MySQL SHA2 poiché non è salata.
Tuttavia, solo per provare, io ho questo lavoro utilizzando la funzione SQL-side:
from sqlalchemy import func, TypeDecorator, type_coerce
from sqlalchemy.dialects.mysql import CHAR, VARCHAR, INTEGER
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
class SHA2Password(TypeDecorator):
"""Applies the SHA2 function to incoming passwords."""
impl = CHAR(64)
def bind_expression(self, bindvalue):
return func.sha2(bindvalue, 256)
class comparator_factory(CHAR.comparator_factory):
def __eq__(self, other):
local_pw = type_coerce(self.expr, CHAR)
return local_pw == func.sha2(other, 256)
class User(Base):
__tablename__ = 'Users'
_id = Column('userID', INTEGER(unsigned=True), primary_key=True)
username = Column(VARCHAR(length=64))
password = Column(SHA2Password(length=64))
def __init__(self, username, password):
self.username = username
self.password = password
Questo è stato copiato dall'esempio 2 a http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DatabaseCrypt
Così che funziona e mi permette di utilizzare la funzione incorporata di MySQL SHA2 (chiamando func.sha2()
) e fare esattamente ciò che voglio. Tuttavia, ora sto cercando di rimpiazzarlo con PassLib sul lato Python.
PassLib presenta due funzioni: una di creare una nuova hash della password, e uno per verificare una password
from passlib.hash import sha256_crypt
new_password = sha256_crypt.encrypt("supersecret")
sha256_crypt.verify("supersecret", new_password)
Non riesco a capire come implementare in realtà questo. Dopo aver letto tutta la documentazione, penso che sia una forma diversa di TypeDecorator, una dichiarazione di tipo personalizzato, un valore ibrido o una proprietà ibrida. Ho provato a seguire this, ma per me non ha alcun senso, né il codice suggerito in realtà viene eseguito.
Quindi, per riassumere la mia domanda: come faccio a sovraccaricare gli operatori =
e ==
in modo che eseguano le operazioni tramite le funzioni di hash appropriate?
Grazie! Questo è nuovo poiché ho fatto questa domanda, ma è esattamente quello che stavo cercando in quel momento! – kc9jud
Che ne dici di aggiungere una colonna di sale a questo modello? C'è un modo per usare un sale con sqlalchemy-utils e store? – steve