The login works from the backend and it goes to the home screen after login on iOS. But how do I do guarantee that the user is actually being logged in?
For example, I have a Label that I would like the user's username to be displayed in, but I don't know how to get the user's username .
I have an idea where I can call the server and it will return the username in JSON format, but isn't this kind of inefficient? What is a better way to do this?
PS. I am a first time iOS programmer
Additional info:
I am also currently using Flask and the Flask-Login extension for the backend. Using the login_user(user) method. This has worked in the past for web dev, but how do I get it to work for iOS dev.
#app.route('/login/', methods=['POST'])
def login():
params = json.loads(request.data)
username = params['username']
password = params['password']
u = User.query.filter_by(username=username).first()
if u:
if utils.check_password_hash(password, u.pw_hash):
login_user(u)
return ('', 200)
else:
return ('', 400)
else:
return ('', 400)
Take a look at Parse.com's iOS SDK (https://www.parse.com/docs/ios_guide#top/iOS). It provides a login form as well as the ability to use a PFUser object to determine if the user is logged in or not. The best thing about Parse is it's free. :)
Calling [PFUser currentUser] will return the user that's logged in or nil if there is no user.
Related
Hello am new at using flask and I have been trying to figure out how to restrict some web pages unless logged in. I tried flask decorators I tried flask decorators but I couldn't understand it so I tried using flask principal which am able to get it running but still cannot be able to stop the access to that webpage.
Code Description
from flask_principal import Permission, RoleNeed
# create permission with a single Need, in this case a RoleNeed
user_permission = Permission(RoleNeed('User'))
#app.route('/home')
def home_page():
return render_template('home.html')
#app.route('/user')
#user_permission.require()
def do_user_index():
return Response('Only if you are a user')
#app.route('/employee')
def employee_page():
user = User.query.all()
return render_template('employee.html', user=user)
def do_employee_page():
with user_permission.require():
return redirect(url_for('login_page'))
You can use session:
First thing we gonna do is create a session at the moment of login:
#app.route(#route that you gonna use to login data verify)
def login():
#login data verification
flask.session["user data"] = #Data you want to use to identify the user
#the next step that you wanna do
Now we gonna verify the session data in the pages, if the user are log in they gonna have their data in flask.session and if not, they not going to have the data in session.
#app.route('/user')
def do_user_index():
if "user data" not in flask.session:
#Redirect to the login page
return Response('Only if you are a user')
You can consult the documentation to learn more about the how to use session.
https://flask.palletsprojects.com/en/2.0.x/quickstart/#sessions
I am trying to set up a POC website in Flask\python to play around with some APIs. I have made a simple login page that redirects to /loggedin. But /loggedin is also accesible by just writing https://mysite/loggedin.html. Is there an easy way to prevent this that does not involve using something like flask-login? I don't want to spend time setting up an SQL user base and such, as I will be the only user of the application.
app = Flask(__name__)
#app.route("/")
def home():
return render_template("home.html")
#app.route("/loggedin")
def innsiden():
return render_template("loggedin.html")
#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('loggedin'))
return render_template('login.html', error=error)
In flask you can maintain on the server "session" information.
A simple method might be to
When user logs in with the correct password, add their username to the session data
When a logged in user visits a "secure" page, flask checks to see if their user id is in the sesson data if 'username' in session:. If it is, they are directed to the correct page, if not they are directed to a log in page
When the user logs out, their user name is removed from the list.
A version of this recipe is described at https://www.tutorialspoint.com/flask/flask_sessions.htm
I am developing a flask app that requires user logins. There are two users currently, one is admin and the other is normal. At the moment, I am using sessions to store the username of the user in then I check to see which username they have and then allow or disallow them access to pages based on their username.
Here is my code:
from flask import Flask, session, redirect, render_template, request
app = Flask(__name__)
app.config["SECRET_KEY"] = <byte string generated by os.urandom(24)>
app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(hours=1)
#app.route("/")
def login_redirect():
if check_login(session, False):
return redirect("/interface")
return redirect("/login")
#app.route("/login", methods=["POST", "GET"])
def login():
error = ""
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
if check_password(username, password):
session["username"] = request.form["username"]
return redirect("/register")
error = "Invalid username or password"
return render_template("login.html", theme_colour=theme_colour, error=error)
def check_password(username, password):
ph = PasswordHasher()
db_hash, salt = database.retrieve_pw_salt(username) # returns hashed/salted password and salt from database
if db_hash is None:
return False # invalid username
try:
ph.verify(db_hash, salt + password)
return True # valid username and password
except exceptions.VerifyMismatchError:
return False # invalid password
def check_login(session, requires_elevated):
if "username" not in session:
return False
elif session["username"] == "admin":
return True
elif session["username"] == "normal" and not requires_elevated:
return True
return False
#app.before_request
def setup():
session.permanent = True # will now abide by 1 hour timeout setting
However, it has recently come to my attention that this may not be very secure. To be honest I'm not really so sure myself, so I was wondering if someone would be able to explain any vulnerabilities to me if there are any, and how I might go about improving the security.
Thanks.
Using session data to authorize permissions isn't considered secure because sessions can be hijacked by stealing session cookies, which would then give the attacker undue influence over a given users account. Since you are using Flask, I suggest you use Flask-Login to manage your sessions. This will give you access to differentiating between fresh and non-fresh logins so that sensitive information can't be accessed and manipulated by a simple session hijacking.
You might also consider implementing third-party authentication through Google, Facebook, LinkedIn or some other major provider so that you can partially outsource some of the heavy lifting associated with providing password and username storage. Two-factor authentication is another way you can improve security on your app, sending texts with unique codes for individuals to log in with or some other second factor. I've linked out to the docs for flask-login at the bottom.
Note: I'd give you code samples, but you've asked an extremely general question about how one might improve security from session-based authorization. I suggest you check out these docs, try to write a better solution for your app's security and then if you have any issues, post another, more specific question about errors in logic or syntax you receive. Good luck!
https://flask-login.readthedocs.io/en/latest/
I am sending out a confirmation token to users after they register to confirm their email. The issue I have is that I cant get to the confirm method as it requires the user to login and once they go to the login method I cant work out how to direct them back to the confirm method.
Note the code is heavily based on the (very good) book 'Flask Web Development' by Grinberg 2014.
We start here with a new user signing up:
#auth.route('/signup', methods=['GET', 'POST'])
def signup():
#validate form and create user
...
token = user.generate_confirmation_token()
send_email(user.email, 'Please Confirm Email Address',
'email/confirm', user=user, token=token)
return redirect(url_for('auth.login'))
return render_template('auth/register.html', form=form)
The new user is sent and email, when the user clicks on the link in the email they are sent to this route:
#auth.route('/confirm/<token>')
#login_required
def confirm(token):
if current_user.confirmed:
return redirect(url_for('main.index'))
if current_user.confirm(token):
#do something here
else:
#message
return redirect(url_for('main.index'))
As login is required to get to the confirm end point, the user is directed here first:
#auth.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is not None and user.verify_password(form.password.data):
login_user(user)
return redirect(request.args.get('next') or url_for('main.index'))
return render_template('auth/login.html', form=form)
The issue I have is that after the user logs in they are not redirected to the confirm route and I can't work out how to redirect to confirm for this case where the user is just logging in so that they can respond to the signup email link. Any ideas?
I'm also learning from this book. Though I don't know what's wrong with you, I can show some key information to you to solve your problem.
First, your test email have the URL like this.(http://127.0.0.1:5000/auth/confirm/eyJleHAiOjE0NjY0ODQwOTAsImFsZyI6IkhTMjU2IiwiaWF0IjoxNDY2NDgwNDkwfQ.eyJjb25maXJtIjo5OX0.npxbWrOYVzX2HYibnDQLNS0FuX-J9XB-TcmZZSPri-8)
Then, you click it and though the code #login_required, so you redirect to the login page, but the URL is not equal to the usual login URL. It has some thing different like this. (http://127.0.0.1:5000/auth/login?next=%2Fauth%2Fconfirm%2FeyJleHAiOjE0NjY0ODQwOTAsImFsZyI6IkhTMjU2IiwiaWF0IjoxNDY2NDgwNDkwfQ.eyJjb25maXJtIjo5OX0.npxbWrOYVzX2HYibnDQLNS0FuX-J9XB-TcmZZSPri-8)
Next, return redirect(request.args.get('next') or url_for('main.index')) this line of your code will get the next confirm URL after the key next=, and visit the confirm page.
So you can check your URL if it has some problems.
Additionally, I recommend you debug your code in pycharm because you can set breakpoint and track variables' changes. Good luck.
Hi I am new to flask and I am trying to create a simple login functionality. Users fill out their username and password (which at this point needs to match the username and password I hardcoded) and if their credentials are approved they are taken to their profile page. The profile page should show the message Hello followed by the username.
The validation is working just fine and the user is taken to the profile page but I can't pass the username from the form (login.html) to the template "profile.html".
Below follows the code. I am sending the code that works but there is no tentative to pass the username.
Thank you!
from flask import *
SECRET_KEY = "super secret"
app = Flask(__name__)
app.config.from_object(__name__)
#app.route('/')
def index():
return render_template('login.html')
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] == 'user' and request.form['password'] == 'pass':
session['loggedin'] = True
return redirect(url_for('profile'))
else:
error="Invalid credentials. Please try again."
return render_template('login.html', error=error)
#app.route('/profile')
def profile():
return render_template('profile.html')
#app.route('/logout')
def logout():
session.pop('loggedin', None)
return redirect(url_for('login'))
if __name__ == '__main__':
app.run(debug=True)
I think you miss the point of your hard work login page.
What about the next page the user will choose to visit? Will you send the username value again? of course not..
I suggest you to define a global var(session? DB data?) that contain the current-logged-in-user-data, so you can use all user's data, not only his username(age?posts? etc..)
One last thing, i use flask-login, i really like it, it simple mange my login session/views and guess what? there is current_user with the current-logged-in-user-data :)
Flask-login summery:
Flask-Login provides user session management for Flask.
It handles the common tasks of logging in, logging out, and remembering your users’ sessions over extended periods of time.
Why not make use of flask's many useful modules? They make flask an attractive microframework for speedy web development.
Flask-login, as stated above, streamlines authentication processes and manages sessions. Flask sessions also automatically stores session data for logged-in users. This allows you to implement a "Remember Me" feature in your login form.
Also, for security purposes, you would want to decorate some of your functions with #login_required, which is part of the flask-login module. This makes sure that the user is automatically redirected to the login page if he or she is not logged in already.
Here is an example of an index function that implements this:
from flask import render_template, session
from flask.ext.login import login_required
#app.route('/')
#login_required
def index():
return render_template("index.html")
You could also use flask.ext.openidto make authentication even more convenient.