check_password_hash ever return False - mysql

I am creating a flask api with login auth but the check_password_hash ever return false and I get a error
in my app.py i'm trying this
from werkzeug.security import generate_password_hash, check_password_hash
#app.route("/signup", methods=["GET", "POST"])
def signup():
if request.method == "POST":
hashed_pw = generate_password_hash(request.form["password"], method="sha256")
new_user = Users(username=request.form["username"], password=hashed_pw)
db.session.add(new_user)
db.session.commit()
return "You've registered successfully."
return render_template("signup.html")
#app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
user = Users.query.filter_by(username=request.form["username"]).first()
if user and check_password_hash(user.password, request.form["password"]):
session['username'] = user.username
return "You are logged in"
else:
return "Your credentials are invalid, check and try again."
return render_template("login.html")
when i print user.password and request.form["password"] it returns hashed
pass -> sha256$SSC4jjZIE3Wm6l7v$74e78b19ddfa3ad62963c93f34d9c6cd93b67e47b4e42e896a726d79
pass -> 1

First make sure that request.form["password"] is returning the password that the user typed.
I don't know how you are hashing the password. Anyways a simple way to do it is using python passlib. it has no known weaknesses.
from passlib.hash import sha256_crypt
to save the hash:
hashed_password = sha256_crypt.hash("ThePassword")
to check the password:
ha256_crypt.verify("password from the form", hashed_password)

Related

Getting Error "type object 'User' has no attribute 'POST' " while login authentication while fetching data from Mysql database

I am stuck here from past 2days. It worked fine when first time I created "createsuperuser" command and I next I modified code by authenticating only Email and Password without username. Again I created newdatabase in Mysql and created "superuser". I also created Regestration method with Posts data into database it is working fine. But when I fetch data(Loin Authentication) it is throwing error. And I dont have any Form models in my App.
from django.contrib.auth.models import User, auth
from django.contrib import messages
def view_comein(request):
if request.method == 'POST':
username = User.POST['username']
# it is not executing here
password = User.POST['password']
user = auth.authenticate(username = username, password = password)
if user is not None:
auth.loginPage(user)
return redirect('/')
else:
messages.info(request, 'Invalied Credentials')
return redirect('loginPage')
else:
return render(request, 'loginPage.html')
Error in browser
Please look closely below code. You are accessing invalid attribute.
def view_comein(request):
if request.method == 'POST':
username = request.POST['username'] #**request; not User**
# it is not executing here
password = request.POST['password']
user = auth.authenticate(username = username, password = password)
if user is not None:
auth.login(request, user) #auth.login; not auth.loginPage

How to make Django views require a user login?

I have a Django project with a login screen; when I enter my username and password I get directed to the home page. This works fine! But nothing is secure, I can just go to the view at /allstudyplans without logging in and see all the information there. My Question is how do I make it so it's not possible to go /allstudyplans without logging in first?
Form
User = get_user_model()
class UserLoginForm(forms.Form):
username = forms.CharField(label='', widget=forms.TextInput(
attrs={
'class': 'form-control',
'autofocus': '',
'placeholder': 'Användarnamn',
}
), )
password = forms.CharField(label='', widget=forms.PasswordInput(
attrs={
'class': 'form-control mt-1',
'placeholder': 'Lösenord',
}
), )
# https://docs.djangoproject.com/en/2.1/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other
def clean(self):
cleaned_data = super().clean()
username = cleaned_data.get('username')
password = cleaned_data.get('password')
if username and password:
user = authenticate(username=username, password=password)
if not user:
raise forms.ValidationError(
'Oh! I can\'t find that user - create user first!')
elif not user.check_password(password):
raise forms.ValidationError(
'Oh! That password is incorrect - try again!')
elif not user.is_active:
raise forms.ValidationError(
'Oh! That user is not active in the database!')
Views
def home(request):
next = (request.GET.get('next'))
form = UserLoginForm(request.POST or None)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
login(request, user)
if next:
return redirect(next)
return redirect('/')
context = {
'form': form,
}
return render(request, "utility-login.html", context)
def Assignments(request):
return render(request, 'nav-side-team.html')
def DetailAssignment(request):
obj = Assignment.objects.all()
context = {
'object': obj
}
return render(request, 'nav-side-project.html', context)
def studyplans(request):
return render(request, 'allStudyplans.html')
def detailStudyplan(request):
return render(request, 'detailStudyplan.html')
Also a Home View in the normal project file (not the app)
#login_required
def homee(request):
return render(request, "allstudyplans.html", {})
Urls in the project:
urlpatterns = [
path('admin/', admin.site.urls),
path('account/', include('accounts.urls')),
path('', include('accounts.urls'))
]
Urls in the app:
urlpatterns = [
path('', views.studyplans),
path('login', views.home),
path('nav-side-team.html', views.Assignments),
path('nav-side-project.html', views.DetailAssignment),
path('allstudyplans.html', views.studyplans),
path('detailStudyplan.html', views.detailStudyplan),
]
Tried this:
#login_required
def Assignments(request):
if not request.user.is_authenticated:
return redirect('%s?next=%s' % ('utility-login.html', request.path))
return render(request, 'nav-side-team.html')
studyplans is missing the decorator login_required.
According to the docs, https://docs.djangoproject.com/en/2.2/topics/auth/default/#the-login-required-decorator, the easiest way should be
#login_required
def studyplans(request):
return render(request, 'allStudyplans.html')
Another way to do it – probably equivalent to the above – is with "mixins":
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
class MyView(LoginRequiredMixin, View):
...
Notice that "mixin" class names should occur first in the list, before View.
(Notice that I also show that there's a "permission-required mixin.")
I guess it just comes down to personal preference, and consistency with the existing source-code of the application.

Querying into PostgreSQL return a NoneType

After creating a user in my database in my app deployed on Heroku, I get into the log page if successful. When I try to log, it does the following query :
result = cur.execute("SELECT * FROM users WHERE username = %s", [username])
Yet it gives me the following error :
018-07-03T15:02:47.167067+00:00 app[web.1]: File "app.py", line 140, in login
2018-07-03T15:02:47.167069+00:00 app[web.1]: if result > 0:
2018-07-03T15:02:47.167071+00:00 app[web.1]: TypeError: '>' not supported between instances of 'NoneType' and 'int'
Yet, the registration query was successful and I'm pretty sure I provided the right credentials. Here is the code involved:
#app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# Get Form Fields
username = request.form['username']
password_candidate = request.form['password']
# Create cursor
#cur = mysql.connection.cursor()
cur = conn.cursor()
# Get user by username
result = cur.execute("SELECT * FROM users WHERE username = %s", [username])
if result > 0:
# Get stored hash
data = cur.fetchone()
password = data['password']
# Compare Passwords
if sha256_crypt.verify(password_candidate, password):
# Passed
session['logged_in'] = True
session['username'] = username
flash('You are now logged in', 'success')
return redirect(url_for('dashboard'))
else:
error = 'Invalid login'
return render_template('login.html', error=error)
# Close connection
cur.close()
else:
error = 'Username not found'
return render_template('login.html', error=error)
Maybe this is because this query used to be for a MySQL database
It does not look like that query would return an integer.
Perhaps you want to select COUNT(*) rather than * to get the number of matching rows.

How do a make a login feature that retrieves the user from the database?

I am making a basic web page that has a sign up page and a login page. I am using google app engine, python, and HTML. This is my user function:
class User(db.Model):
name = db.StringProperty(required=True)
pw_hash = db.StringProperty(required=True)
email = db.StringProperty()
#classmethod
def by_id(cls, uid):
return cls.get_by_id(uid, parent=users_key())
#classmethod
def by_name(cls, name):
u = cls.all().filter('name=', name).get()
return u
#classmethod
def register(cls, name, pw, email=None):
pw_hash = make_pw_hash(name, pw)
return cls(parent=users_key(),
name=name,
pw_hash=pw_hash,
email=email)
#classmethod
def login(cls, name, pw):
u = cls.by_name(name)
if u and valid_pw(name, pw, u.pw_hash):
return u
When I register new users, I put them in the database. They are being stored in the database:
class Register(Signup):
def done(self):
#make sure the user doesn't already exist
u = User.by_name(self.username)
if u:
msg = 'That user already exists.'
self.render('signup-form.html', error_username = msg)
else:
u = User.register(self.username, self.password, self.email)
u.put()
self.login(u)
self.redirect('/blog')
But when I use my login function, I am unable to retrieve the user from the database to use the login feature. It says "login invalid" every time:
class Login(BlogHandler):
def get(self):
self.render('login-form.html')
def post(self):
username = self.request.get('username')
password = self.request.get('password')
u = User.login(username, password)
if u:
self.login()
self.redirect('/blog')
else:
msg = 'Invalid login'
self.render('login-form.html', error = msg)
When I signup, it's supposed to recognize that the User is already in the database. However, I am able to sign up with the same credentials every time. Here is my signup Handler:
class Signup(BlogHandler):
def get(self):
self.render("signup-form.html")
def post(self):
have_error = False
self.username = self.request.get('username')
self.password = self.request.get('password')
self.verify = self.request.get('verify')
self.email = self.request.get('email')
params = dict(username = self.username,
email = self.email)
if not valid_username(self.username):
params['error_username'] = "That's not a valid username."
have_error = True
if not valid_password(self.password):
params['error_password'] = "That wasn't a valid password."
have_error = True
elif self.password != self.verify:
params['error_verify'] = "Your passwords didn't match."
have_error = True
if not valid_email(self.email):
params['error_email'] = "That's not a valid email."
have_error = True
if have_error:
self.render('signup-form.html', **params)
else:
self.done()
def done(self, *a, **kw):
raise NotImplementedError
Here is the bloghandler function which is the base line for all the other functions:
class BlogHandler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
params['user'] = self.user
return render_str(template, **params)
def render(self, template, **kw):
self.write(self.render_str(template, **kw))
def set_secure_cookie(self, name, val):
cookie_val = make_secure_val(val)
self.response.headers.add_header(
'Set-Cookie',
'%s=%s; Path=/' % (name, cookie_val))
def read_secure_cookie(self, name):
cookie_val = self.request.cookies.get(name)
return cookie_val and check_secure_val(cookie_val)
def login(self, user):
self.set_secure_cookie('user_id', str(user.key().id()))
def logout(self):
self.response.headers.add_header('Set-Cookie', 'user_id=; Path=/')
def initialize(self, *a, **kw):
webapp2.RequestHandler.initialize(self, *a, **kw)
uid = self.read_secure_cookie('user_id')
self.user = uid and User.by_id(int(uid))
Here is the link to the GITHUB:
https://github.com/keldavis/registration
Here is the link to the website:
registration-148718.appspot.com
How do I make my signup page recognize an already created user? And how can I make my login page retrieve my user from the database and perform a valid login?
Your line
u = cls.all().filter('name=', name).get()
should either be
u = cls.all().filter('name =', name).get()
or
u = cls.all().filter('name', name).get()
per Google docs (note the missing space character / the = character being optional):
property_operator: String consisting of a property name and an optional comparison
operator (=, !=, <, <=, >, >=, IN), separated by a space: for example,
'age >'. If just a property name is specified without a comparison
operator, the filter compares for equality (=) by default.
(also note that you should be using google.appengine.ext.ndb instead of google.appengine.ext.db and really shouldn't be implementing authentication / authorization / hashing / etc on your own in real apps)

uwsgi two MySql errors after some time from starting application

I'm using uwsgi for my python application. I am new to uwsgi.
When I want to run uwsgi in the background I do this:
uwsgi --http 127.0.0.1:1088 --wsgi-file app.py --callable app --master --processes 1 --workers 1 --threads 1 --daemonize=logs.txt
then after some time e.g. 10 minutes when I try to login to my test account on my live website I always get 500 internal error. In logs.txt file I found this exception:
OperationalError("(_mysql_exceptions.OperationalError) (2006, 'MySQL server has gone away')")
or sometimes this one
StatementError("(sqlalchemy.exc.InvalidRequestError) Can't reconnect until invalid transaction is rolled back",)
What I did:
I found that --lazy-apps or --lazy should solve the problem but it didn't.
Here is how I used lazy-apps
uwsgi --http 127.0.0.1:1065 --wsgi-file app.py --callable app --master --lazy-apps --processes 1 --workers 1 --threads 1 --daemonize=logs.txt
Then I tried to set POOL_RECYCLE to less than 5m like this (but still the problem occurs):
app.config['SQLALCHEMY_POOL_RECYCLE'] = 285
I read that I should disable pooling using NullPool but to be honest I don't know how to do it. Here link is a list of configuration keys but there is no SQLALCHEMY_POOLCLASS
below is my code. How can I solve my problem ? Thanks
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://brrr:brrr#localhost/grrr'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False
app.config['SQLALCHEMY_POOL_RECYCLE'] = 285
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
from models import *
app.secret_key = 'super secret key'
login_manager = LoginManager()
login_manager.init_app(app)
from models import *
login_manager.login_view = "login"
#login_manager.user_loader
def load_user(user_id):
return User.query.filter(User.id == int(user_id)).first()
#app.route('/')
def index():
return render_template('index.html')
#app.route('/success')
def success():
return render_template('success.html')
#app.route('/login', methods=['GET','POST'])
def login():
error = None
if request.method == 'POST':
user = ser.query.filter_by(username=request.form['username']).first()
if user is not None:
user_pass = request.form['password']
if bcrypt.check_password_hash(user.password, user_pass):
login_user(user)
return redirect(url_for('success'))
else:
error = 'error'
else:
error = 'error'
return render_template('login.html', error=error)
#app.route('/signup', methods=['GET','POST'])
def signup():
user_name_error = None
email_error = None
if request.method == 'POST':
user = User(
username=request.form['username'],
password=request.form['password']
)
db.session.add(user)
db.session.commit()
login_user(user)
return redirect(url_for('success'))
return render_template('signup.html')
#app.route('/logout')
def logout():
logout_user()
return redirect(url_for('index'))
if __name__ == '__main__':
app.run()
I did the same thing like PizzaPleb did here link so I re-init my db like this
db.init_app(app)
I pasted it here
...
from models import *
login_manager.login_view = "login"
**db.init_app(app)**
...
and I got rid off that exception.