I am trying to validate an encrypted password for login
purposes in Pyramid. So that if the user and password match then the system will authorize the user. At the moment I am finding it difficult to write a function to compare passwords when one is encrypted in the database and the the password being entered into Pyramid's login
form is unencrypted. Right now, I have no verification occurring in the login view.
I am new to this entire process of working with security measures/code and want to do this right. I was looking at this Auth tutorial, however the encryption in the User
class is slightly different and I am using Pyramid's Auth kit. Any guidance on how to do this successfully and smartly would be highly appreciated.
Software: Python 2.7.9, Pyramid 1.5.7, SQLAlchemy 1.0.9
database class:
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 "<User(username ='%s', password='%s', email='%s')>" % (self.username, self.password, self.email)
views
@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,
)
WARNING INSECURE CODE FOLLOWS
The code below is NOT a SECURE and SAFE way to store/verify user passwords. Please use a library that provides secure password storage, such as passlib which is specifically designed to securely store passwords.
You hash the user's password in your
User.__init__
usingself.password = hashlib.sha224(password).hexdigest()
. Just use a similar method to validate it:And use it in your view:
Please modify your code, add the excellent passlib library, and use secure password storage using bcrypt as the hashing algorithm.
In your projects setup.py add the following as requirements:
And then use the following code snippet for your model: