Authentication in Flask application using dictionary database structure - python

I am creating a basic application to demonstrate the register and login activities in Flask using sessions. For the below code, each user available in the dictionary should be able to login. However, the application only accepts the login for the first user named 'Mary'. I don't understand where did it went wrong.
from flask import Flask, app, session, render_template, request,redirect, url_for, jsonify
app = Flask(__name__)
app.config['SECRET_KEY'] = "Zd9TUg1aE03bHc28"
#app.route('/')
def load():
return render_template("authusers.html")
class Mydatabase:
appdb=[{'username':'Mary','password':'Password#123'},
{'username':'John','password':'Password#456'},
{'username':'Tara','password':'Password#789'}]
mydbusers=Mydatabase()
#app.route('/login',methods = ['GET','POST'])
def success():
if request.method == "POST":
username_val = request.form['user_id']
userpassword_val = request.form['user_password']
for authuser in Mydatabase.appdb:
for authpassword in authuser.values():
if authuser['username'] == username_val and authpassword['password'] == userpassword_val:
session['reg_user'] = username_val
return f'{session.get("reg_user")} have successfully logged into the application';
else:
return redirect(url_for('register'))
#app.route('/logout', methods=['GET','POST'])
def logout():
if 'reg_user' in session:
session.pop('reg_user',None)
return render_template("authusers.html")
#app.route('/register', methods=['GET','POST'])
def register():
return render_template('register.html')
#app.route('/reg_success',methods=['GET','POST'])
def reg_success():
newusercred={'username':request.form['user_id'], 'password':request.form['user_password']}
mydbusers.appdb.append(newusercred)
# return jsonify(Mydatabase.appdb)
return render_template("authusers.html")
if __name__=="__main__":
app.run(debug=True)

I see some logical issue in your code
Try like this ->
class Mydatabase:
appdb=[{'username':'Mary','password':'Password#123'},
{'username':'John','password':'Password#456'},
{'username':'Tara','password':'Password#789'}]
username_val = 'Tara'
userpassword_val = 'Password#789'
d = [a for a in Mydatabase.appdb if a["username"] == username_val and a["password"]==userpassword_val]
if d:
print(f'have successfully logged into the application')
else:
print(f'Wrong credentials')
There are some unwanted loops in your code, and you do return even in the else of part.

Related

NameError: name 'logged' is not defined, Flask Python

I have a Python code with using framework Flask, that check if admin logged (logged = True) to render admin page, if admin is not logged (logged = False), redirecting to login page.
#app.route('/admin_login', methods=['POST', 'GET'])
def admin_login():
if request.method == 'POST':
login = request.form['login']
passsword = request.form['password']
if (login == 'admin') and (passsword == 'admin_pass'):
logged = True
return redirect('/admin_page'), logged
else:
return "Wrond login and passsword!"
else:
return render_template('admin_login.html')
#app.route('/admin_page')
def admin_page():
if logged == True:
return render_template('admin_page.html')
else:
return redirect('/admin_login')
But I get an error in if logged == True: - NameError: name 'logged' is not defined. I tried to make logged global but it didn't helped. So how can I make logged defined and use it in function admin_page?
You should avoid having a global logged_in variable on the server. Then anybody will be allowed to use your website after a successful login! You should use a session variable instead.
Session data is stored on top of cookies and encrypted. For this encryption, a Flask application needs a defined SECRET_KEY. A Session object is also a dictionary object containing key-value pairs.
Add this near the top of your main script if you haven't already got it:
from flask import Flask, session, redirect, url_for, escape, request, flash
app = Flask(__name__)
app.secret_key = 'any random string’
Then change your function admin_login() to set the session variable:
#app.route('/admin_login', methods=['POST', 'GET'])
def admin_login():
if request.method == 'POST':
login = request.form['login']
passsword = request.form['password']
if not 'logged_in' in session:
if (login == 'admin') and (passsword == 'admin_pass'):
session['logged_in'] = True
return redirect(url_for("admin_page"))
else:
flash("Wrong login and passsword!")
return render_template('admin_login.html')
else:
return redirect(url_for("admin_page"))
else:
if "logged_in" in session:
return redirect(url_for("admin_page"))
return render_template("admin_login.html")
Then change your admin_page() function to check this session variable:
#app.route('/admin_page')
def admin_page():
if 'logged_in' in session:
return render_template('admin_page.html')
else:
return redirect(url_for('admin_login'))
You would also need a logout end point to pop out the session variable:
#app.route('/logout')
def logout():
session.pop('logged_in', None)
return redirect(url_for('index'))

Why do I lose the session information on redirect in Flask app?

I was following one of cs50's lectures and writing the same code in vscode as in the lecture. For some reason it works in the course's ide but when it is in vscode on my PC the session forgets the input after redirection. Where is the problem and Is it possible to fix it?
from flask import Flask, render_template, request, redirect, session
from flask_session import Session
app = Flask(__name__)
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SECRET_KEY'] = 'randomkey'
Session(app)
#app.route('/')
def tasks():
if 'todos' not in session:
session['todos'] = []
return render_template('tasks.html', todos=session['todos'])
#app.route('/add', methods=["GET", "POST"])
def add():
if request.method == "GET":
return render_template('add.html')
else:
todo = request.form.get('task')
session['todos'].append(todo)
return redirect('/')

Flask: request.referrer returns none when referred from external URL

New to Flask and Python. I've cloned a github Flask chat app example and am trying to get a referrer URL (i.e. the URL the user was in before going into my app). However, when I run the app locally, the referrer link always come back as None if the request comes from an external URL. If it is sent from within the app, I am getting the right referrer URL.
Here's the relevant bits of code. I've tried looking at previous questions, but couldn't find a solution.
My routing logic:
from flask import session, redirect, url_for, render_template, request
from . import main
from .forms import LoginForm
#main.before_request
def before_request():
print("Ref1:", request.referrer)
print("Ref2:", request.values.get("url"))
#main.route('/', methods=['GET', 'POST'])
def index():
form = LoginForm()
ip_address = request.access_route[0] or request.remote_addr
print("ip_addr:", ip_address)
if form.validate_on_submit():
session['name'] = form.name.data
session['room'] = form.room.data
return redirect(url_for('.chat'))
elif request.method == 'GET':
form.name.data = session.get('name', '')
form.room.data = session.get('room', '')
return render_template('index.html', form=form)
#main.route('/chat')
def chat():
name = session.get('name', '')
room = session.get('room', '')
if name == '' or room == '':
return redirect(url_for('.index'))
return render_template('chat.html', name=name, room=room)
My main app code is:
#!/bin/env python
from app import create_app, socketio
app = create_app(debug=True)
if __name__ == '__main__':
socketio.run(app)
Would really appreciate any advice.
Thanks!

How to integrate login required decorator to flask routes with a static user ID and password?

I am new to flask and python, i am trying to add login required and all routes other than home page. I read about flask-login module, haven't had any success. Looking for suggestions !
I tried using flask-login and prevent access of "/data" route. It did not work. My login requirement is very simple, allow login if user pass is admin/admin. And make sure the user is logged in for all subsequent routes.
Here is my flask code
from flask import Flask, render_template, redirect, url_for, request
import subprocess
import os
import datetime
import time
app = Flask(__name__)
#app.route("/")
def home():
now = datetime.datetime.now()
timeString = now.strftime("%Y-%m-%d %H:%M")
templateData = {
'title' : 'HELLO!',
'time': timeString
}
return render_template('main.html', **templateData)
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
return redirect(url_for('data'))
return render_template('login.html', error=error)
#app.route("/data")
def data():
now = datetime.datetime.now()
timeString = now.strftime("%Y-%m-%d %H:%M")
templateData = {
'title' : 'HELLO!',
'time': timeString
}
return render_template('api.html', **templateData)
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
I dont want /data route to be accessed without login as admin/admin
flask_login should do the trick.
import and use the '#login_required' decorator on any route that you want to make unavailable to users who aren't currently logged in.
from flask_login import login_required
#app.route("/data")
#login_required
def data():
...
...
leave the decorator off of any routes that don't require login.
since you only have need for generic authentication you might look into session login.
for this, you'll need a secret key...
import secrets
app = Flask(__name__)
app.config['SECRET_KEY'] = secrets.token_hex(16)
and an example usage of flask session management.
from flask import session
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
session['logged_in'] = True
return redirect(url_for('data'))
return render_template('login.html', error=error)

Flask server not working properly with CodernityDB

I'm trying to complete the Flask tutorial between this and this to have something very simple using CodernityDB instead of sqllite, and I need to execute the app to be able to study all the CodernityDB methods I need. But the server is not working properly, the localhost tell me there is an Internal error, but I can't figure out the way to debug it.
Here is my code (flaskr.py), the templates are here:
from __future__ import with_statement
from flask import Flask, request, session, g, redirect, url_for, \
abort, render_template, flash
from CodernityDB.database_thread_safe import ThreadSafeDatabase
from CodernityDB.database import RecordNotFound
# configuration
DATABASE = '/tmp/flaskr.db'
DEBUG = True
SECRET_KEY = 'development key'
# pending
USER = 'admin'
PASSWORD = 'default'
app = Flask(__name__)
##app.config.from_object(__name__)
cdb = ThreadSafeDatabase(DATABASE)
if cdb.exists():
cdb.open()
cdb.reindex()
else:
from database_indexes import WithXIndex
cdb.create()
cdb.add_index(WithXIndex(cdb.path, 'x'))
#app.before_request
def before_request():
g.db = cdb
#app.route('/')
def show_entries():
## return "Hello World! This is powered by Python Backend."
cur = db.get('x',10,with_doc=True)
entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
return render_template('show_entries.html', entries=entries)
#app.route('/add', methods=['POST'])
def add_entry():
## return "Add new entry"
if not session.get('logged_in'):
abort(401)
g.db.insert(dict(x=request.form['title'], name=request.form['text']))
flash('New entrey was succesfully posted')
return redirect(url_for('show_entries'))
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in')
return redirect(url_for('show_entries'))
return render_template('login.html', error=error)
#app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
if __name__ == '__main__':
app.run()
## app.run(host='0.0.0.0')
## app.run(debug= True)
## app.run(host='127.0.0.1', port=5000)
database_indexes.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from CodernityDB.hash_index import HashIndex
from CodernityDB.tree_index import TreeBasedIndex
from hashlib import md5
class WithXIndex(HashIndex):
def __init__(self, *args, **kwargs):
kwargs['key_format'] = 'I'
super(WithXIndex, self).__init__(*args, **kwargs)
def make_key_value(self, data):
a_val = data.get("x")
if a_val is not None:
return a_val, None
return None
def make_key(self, key):
return key
I didn't create the environment variable because I want to use another approach for the configuration, maybe a file, and the config.from_object is commented because when I executed it with it shows Restarting with stat.

Categories

Resources