Search code examples
pythoniisflask

Python/Flask Login form throws 500 error on IIS


Due to my restrictions at work, I have to rely on hosting my webapp on IIS 7.5. I configured IIS to serve the application via wfastcgi.py.

The issue is, that a login form, throws an HTTP 500 error on IIS, when clicking on the login button. The site gets loaded without issue. Also, code works perfectly fine, when I am running it on the flask development server.

I have an extended version of the code, with access to a sqlite DB. I was able to narrow down the issue to the login session creation part. I am not sure, whether the issue is about the way how IIS handles POST and GET requests with wfastcgi.py, or something else.

Here's the simplified version of the code, which throws the same error: UPDATE: Changed the view functions to the proper return redirect.

import wiw_ad_controller as parser
import sys
from flask import Flask, flash, render_template, redirect, url_for, request, session, abort
import os



app = Flask(__name__)

@app.route('/')
@app.route('/index', methods=['GET', 'POST'])
def index():
    if not session.get('logged_in'):

        return render_template('login.html')        
    else:
        return render_template('index.html')        


@app.route('/login', methods=['POST'])
def login():
    if request.form['username'] == 'admin' and request.form['password'] == 'admin':
        session['logged_in'] = True
        flash("Login was successfull")
    else:
        flash("Wrong password!")
    return redirect(url_for('index')) 


@app.route('/search', methods=['GET','POST'])
def lookup_data():
    if (session.get('logged_in')==True):
        if request.method == 'POST' or request.method == 'GET':

            if (request.form['gpn'] and request.form['gpn'].isdigit()):

                #code removed - not needed
                return render_template('fetched_data.html', user_wiw=user_wiw, user_ad=user_ad)
            else:
                flash('Wrong ID')
            return index()
    return redirect(url_for('index')) 


@app.route("/logout")   
def logout():
    session['logged_in'] = False
    return redirect(url_for('index')) 


@app.errorhandler(500)
def internal_error(exception):
    app.logger.exception(exception)
    return render_template('500.html'), 500 


@app.errorhandler(404)
def internal_error(exception):
    app.logger.exception(exception)
    return render_template('404.html'), 404




if __name__ == '__main__':
    app.secret_key=os.urandom(12)
    app.run(debug=True)

Solution

  • Found out the issue. I didn't realize, that by calling my script via wfastcgi.py, the main function never runs.

    The login feature did not work, because it needed app.secret_key=os.urandom(12) to be run first.

    I used the following code by Miguel Grinberg to find out what the issue is, since debug=True did not provide any output in a IIS prod environment.

    @app.errorhandler(500)
    def internal_error(exception):
        app.logger.exception(exception)
        file_handler = RotatingFileHandler('C:\inetpub\wwwroot\logs.log', 'a', 1 * 1024 * 1024, 10)
        file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
        app.logger.setLevel(logging.INFO)
        file_handler.setLevel(logging.INFO)
        app.logger.addHandler(file_handler)
        app.logger.info('microblog startup')
        return render_template('500.html'), 500 
    

    Hope, this will help others in the same situation as me.

    Note: Read/Write permissions have to be set on wwwroot and all files in order for this to work.

    You also need to import logging, from logging import RotatingFileHandler, import render_template from flask, create 500.html file in tempaltes folder.