Almacenamiento y validación de contraseña encriptada para iniciar sesión en Pyramid

Estoy tratando de validar una contraseña encriptada para propósitos de login de login en Pyramid. De modo que si el usuario y la contraseña coinciden, el sistema autorizará al usuario. En este momento me resulta difícil escribir una función para comparar las contraseñas cuando una está cifrada en la base de datos y la contraseña que se ingresa en el formulario de login de login de Pyramid no está encriptada. En este momento, no tengo ninguna verificación en la vista de inicio de sesión.

Soy nuevo en todo este proceso de trabajar con código / medidas de seguridad y quiero hacer esto correctamente. Estaba mirando este tutorial de autenticación , sin embargo, el cifrado en la clase de User es ligeramente diferente y estoy usando el kit de autenticación de Pyramid. Cualquier orientación sobre cómo hacer esto con éxito y de manera inteligente sería muy apreciada.

Software: Python 2.7.9, Pyramid 1.5.7, SQLAlchemy 1.0.9


clase de base de datos:

 class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(15), nullable=False, unique=True) email = Column(String(300)) password = Column(String(300), nullable=False) def __init__(self, username, password, email): self.username = username self.password = hashlib.sha224(password).hexdigest() self.email = email def __repr__(self): return "" % (self.username, self.password, self.email) 

puntos de vista

 @view_config(route_name='login', renderer='templates/login.jinja2') @forbidden_view_config(renderer='templates/login.jinja2') def login(request): login_url = request.route_url('login') referrer = request.url if referrer == login_url: referrer = '/' # never use the login form itself as came_from came_from = request.params.get('came_from', referrer) message = '' login = '' password = '' if 'form.submitted' in request.params: login = request.params['login'] password = request.params['password'] user = api.retrieve_user(login) # need some way to validate password if user is not None: # need to check user/password here, redirect if wrong headers = remember(request, login) return HTTPFound(location = came_from, headers = headers) message = 'Failed login' return dict( message = message, url = request.application_url + '/login', came_from = came_from, login = login, password = password, ) 

Modifique su código, agregue la excelente biblioteca de passlib y use el almacenamiento seguro de contraseñas usando bcrypt como algoritmo de hash.

En sus proyectos setup.py agregue lo siguiente como requisitos:

  • bcrypt
  • pasarela

Y luego use el siguiente fragmento de código para su modelo:

 from passlib.hash import bcrypt class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(15), nullable=False, unique=True) email = Column(String(300)) password = Column(String(300), nullable=False) def __init__(self, username, password, email): self.username = username self.password = bcrypt.encrypt(password) self.email = email def validate_password(self, password): return bcrypt.verify(password, self.password) def __repr__(self): return "" % (self.username, self.password, self.email) 

ADVERTENCIA EL CÓDIGO DE INSEGURACIÓN SIGUE

El siguiente código NO es una forma SEGURA y SEGURA de almacenar / verificar las contraseñas de los usuarios. Utilice una biblioteca que proporcione almacenamiento seguro de contraseñas, como passlib que está diseñado específicamente para almacenar contraseñas de forma segura.


Usted tiene la contraseña del usuario en su User.__init__ usando self.password = hashlib.sha224(password).hexdigest() . Solo usa un método similar para validarlo:

 class User(Base): # Your existing code unchanged def validate_password(self, password): return self.password == hashlib.sha224(password).hexdigest() 

Y utilízalo en tu vista:

 user = api.retrieve_user(login) if user is not None and user.validate_password(password): # You logic on success