0

I have a chatbot web app hosted trough Flask, and trough flask_login you can log in and use the app. But for some reason, if I log in as different users on different web browsers, the different users are all in the same session. Meaning if user X asks a question and the bot answers, user Y can follow up with another question and continue the conversation with the bot that was initially started by user X. How do I give each user a seperate Session? Worth mentioning I'm not saving each user in a DB when using flask_login. Here is my code:

from flask import Flask, request, jsonify, session, redirect, url_for, g, flash
from flask_login import login_required, login_user, logout_user, LoginManager, UserMixin, current_user

import sys
import bot
import logging
import uuid

app = Flask(__name__)
app.config.from_object(__name__)
app.secret_key = str(uuid.uuid4())
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////'
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.session_protection = "strong"
class User(UserMixin):
    def __init__(self, id):
        self.id = id



@login_manager.user_loader
def load_user(user_id):
    return User(user_id)

#
# Do not change this variable in this project.  This access token is for a bot that
# has been made for this template.
#

# make a random UUID for the SESSION_ID
SESSION_ID = str(uuid.uuid4())

chat_bot = bot.Bot(CLIENT_ACCESS_TOKEN)
try:
    chat_bot.initialize()
except Exception:
    print("Something went wrong when initializing the chatbot.")
    sys.exit(1)




@app.route('/', methods=['GET', 'POST'])
def login():
    #TODO first check if user is in session
    print("bruker:" + str(g.user))
    if g.user:
        return redirect(url_for('chat_template'))
    else:
        if request.method == 'POST':
            # TODO add password verification, current passes only if password is '1'
            if request.form['password'] == '1':
                session['user'] = request.form['username']
                return redirect(url_for('chat_template'))
            else:
                #TODO handle wrong password
                flash('Invalid credentials')
        return app.send_static_file("login.html")


@app.route("/logout")
@login_required
def logout():
    print("kommer til logout")
    session.pop('user', None)
    return redirect(url_for("login"))

@app.route('/chat_template', methods=['GET', 'POST'])
@login_required
def chat_template():
    print("chat_temp:" + str(g.user))
    if g.user:
        print("g.user finnes")
        if request.method == 'POST':
            message = request.values.get('message', None)
            result = chat_bot.handle_message(message, {})
            return jsonify(result)
        else:
            return app.send_static_file("chat_template.html")
    else:
        return redirect(url_for("login"))


@app.before_request
def before_request():
    if 'user' in session:
        print("logger inn")
        g.user = SESSION_ID
        login_user(User(SESSION_ID))
    else:
        print("logged out")
        g.user = None
        logout_user()

@app.before_first_request
def before_first_request():
    g.user = None
    if 'user' in session:
        print("setter g.user")
        g.user = session['user']

@app.errorhandler(500)
def server_error(e):
    logging.exception('An error occurred during a request.')
    return """
    An internal error occurred: <pre>{}</pre>
    See logs for full stacktrace.
    """.format(e), 500


if __name__ == '__main__':

    app.run(host='127.0.0.1', port=8080, debug=True)
  • Why are you creating just a single global `SESSION_ID`? All your users have the same value. – Martijn Pieters Nov 21 '17 at 07:58
  • I thought this code was initialized for each user... Is that where my problem lies? – user3541869 Nov 21 '17 at 08:05
  • No, globals are set just once, when importing. If you need a new session id for each user logging in, create it *in the login function*. – Martijn Pieters Nov 21 '17 at 08:06
  • Do I even need to set session ID, I thought flask_login was supposed to handle that mess... I'll try setting the user id to session id in login – user3541869 Nov 21 '17 at 08:09
  • @MartijnPieters It did not work... – user3541869 Nov 21 '17 at 08:20
  • Your `before_first_request` is redundant and not needed. `session` is unique per browser. Flask-Login lets you handle logging in and out, and tying the session to application specific user data. Your unique UUID can be your application-specific data, that's fine. But nothing in `chat_template` uses the uses information. – Martijn Pieters Nov 21 '17 at 08:25
  • How is your chat bot differentiating between users? If you need separate instances of `bot.Bot()`, then you need to create those on login and store them such that you can find them again for each user request to `chat_template`. – Martijn Pieters Nov 21 '17 at 08:26
  • @MartijnPieters I see, thank you!! – user3541869 Nov 21 '17 at 08:28

0 Answers0