Flask session not persisting - python

Am running with Python 2.7, Apache + mod_wsgi on CentOS 6.3
Things work fine when I am on localhost. However, when I run the code on a vm in Azure, I do not see the session information being persisted across pages.
Basically in my views, I have something like:
#frontend.route('/')
def index():
session['foo'] = 'bar'
print session['foo']
return redirect(url_for("frontend.page2"))
#frontend.route('page2')
def page2():
print session
The print output is:
bar
<SecureCookieSession {}>
My wsgi configuration for apache is:
WSGISocketPrefix /var/run/wsgi
<VirtualHost *:80>
ServerName example.com
ServerAlias example.com
WSGIDaemonProcess myproj threads=5 processes=5
WSGIScriptAlias / /home/mydir/myproj/apache/myproj.wsgi
<Directory /home/mydir/myproj>
WSGIScriptReloading On
WSGIProcessGroup myproj
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
I have the secret_key set:
app.secret_key = os.urandom(24)
I have tried with both setting SERVER_NAME but it doesn't help:
app.config['SERVER_NAME'] = 'example.com'
Any ideas on how I can debug this more?
Thanks!

Don't use app.secret_key = os.urandom(24)!
You're supposed to enter a static value here, not read from os.urandom each time. You've probably misunderstood the example in the docs, it shows you how you can read random data from os.urandom, but it also clearly states:
Just take that thing and copy/paste it into your code and you’re done
If you read it at runtime, then each of your worker processes will have a different secret key! That means if a request is handled by a different worker, the session will break because the cookie is signed with the wrong secret key.

Related

Django CSRF Malfunction after using HTTPS

I know that this problem is occurs many times here. But none of them has working for me right now. I've been struggling in this error since I change the protocol of my app to https using apache2 and LetsEncrypt. I try the configurations in settings but it doesn't solve the problem.
# settings.py
CSRF_COOKIE_DOMAIN = ".myapp.ml"
CSRF_COOKIE_SECURE = True
CSRF_USE_SESSIONS = True
SESSION_COOKIE_SECURE = True
Ofcourse in every forms with POST method required that I have has {% csrf_token %} in there. It also shows in request data. This errors occurs in Log in and Sign Up forms.
Inside the app after I add csrf_exempt in login and signup, I use DRF and when I make requests like POST, DELETE, PUT etc... It only shows the error {"detail":"CSRF Failed: Referer checking failed - no Referer."}
Here is my apache2 configuration file:
<IfModule mod_ssl.c>
<VirtualHost *:443>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName www.myapp.ml
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /app /home/app/app-src/static_root
<Directory /home/app/app-src/static_root>
Require all granted
</Directory>
Alias /media /home/app/app-src/media
<Directory /home/app/app-src/media>
Require all granted
</Directory>
<Directory /home/app/app-src/Project>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/app/app-src/Project/wsgi.py
WSGIDaemonProcess Project python-path=/home/app/app-src python-home=/home/app/app-src/venv
WSGIProcessGroup Project
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
WSGIPassAuthorization On
SSLCertificateFile /etc/letsencrypt/live/www.myapp.ml/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.myapp.ml/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
NOTE: That is only occuring when I use the HTTPS protocol.
UPDATE
I start to find the bug here and I found it on my OWN HTML FILE! I Literally forgot that one of my meta tags set the referrer to no-referrer so I just replace it with origin then everything works fine.

Images not showing over SSL on apache2 with python script

I know this question has been asked several times, but I am all out of ideas and have been reading everywhere about this.
I am running Ubuntu 17.04 and Apache 2.4.25 to host a web server. I have generated my own SSL certificate. Since doing this, I am unable to view any images over SSL. Currently, I can confirm the path is working, the file is in tact and URL is correct, as I can access this typing the http URL into my browser.
If I go to the web inspector whilst loading my site, if I click on any image it gives me a 404 error.
How do I get these images to load over SSL.
My apache2 config is:
<VirtualHost *:80>
ServerName localhost
ServerAdmin info#****.com
DocumentRoot /var/www/****.com/pay
Redirect /secure https://****.com/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
<VirtualHost *:443>
SSLEngine On
SSLCertificateFile /etc/ssl/certs/****.com.crt
SSLCertificateKeyFile /etc/ssl/private/****.com.key
SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt
SetEnv SECRET_KEY ****
SetEnv PUBLISHABLE_****
ServerAdmin info#****.com
ServerName www.****.com
DocumentRoot /var/www/****.com/pay/static
WSGIDaemonProcess webtool threads=5 python-path=/var/www/****.com/pay
WSGIScriptAlias / /var/www/****.com/pay/webtool.wsgi
EnableMMAP off
EnableSendfile off
<Directory /var/www/****.com/pay>
Options +ExecCGI
WSGIProcessGroup webtool
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
and I have a python script running to do my routes:
import os
import stripe
import cgi
print "Context-type: text/html"
from flask import Flask, render_template, request, redirect, send_from_directory
from flask import request
from flask import json
stripe_keys = {
'secret_key': os.environ['SECRET_KEY'],
'publishable_key': os.environ['PUBLISHABLE_KEY']
}
stripe.api_key = stripe_keys['secret_key']
app = Flask(__name__, static_url_path='')
#app.route('/')
def index():
return render_template('index.html', key=stripe_keys['publishable_key'])
#app.route("/hello")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host="127.0.0.1", port="5050")
#app.route("/charge", methods=['POST'])
def charge():
# Amount in cents
amount = 500
customer = stripe.Customer.create(
email=request.form['stripeEmail'],
source=request.form['stripeToken']
)
charge = stripe.Charge.create(
customer=customer.id,
receipt_email=request.form['stripeEmail'],
amount=amount,
currency='usd',
description='Donation'
)
return render_template('charge.html', amount=amount)
I cannot work out if I need to set a route in my python script to allow images to be fetched, or I am missing something else.
I am calling the image in my index.html file with:
with the 'img' folder being in the same location as index.html. Please help.
Your image requests are being sent to WSGI, if you want Apache to handle them, you'll have to "undo" the WSGIScriptAlias of /.
I'm not a WSGI user, but it seems like you could block this from
running conditionally by putting this in your vhost:
RewriteEngine ON
RewriteRule ^/img/ - [L]
Even though this is a no-op, it should block this part of WSGi from running.

Flask WSGI subdomain dispatching causing 404s on app instances

My goal is for my Flask app to switch databases based on the subdomain.
The subdomain dispatcher described in the docs is useful and I'm using something based off it
Everything seems to work fine but only 2 instances seem to work at a given time despite the SubDomainDispatcher having multiple instances loaded. The other instances give out 404s.
My create_app function is as follows:
def create_app(subdomain):
app = Flask("proj", static_folder="../static", template_folder="../templates")
with app.app_context():
app.config.from_object('proj.config')
app.config.update(
SQLALCHEMY_DATABASE_URI = 'mysql://root:password#localhost:3306/' + subdomain + '_proj',
HOST = subdomain + app.config["HOST"],
)
from proj.models import db, Models
engine = sqlalchemy.create_engine("mysql://root:passwordT#localhost:3306")
engine.execute("CREATE DATABASE IF NOT EXISTS "+subdomain+"_proj")
engine.execute("use "+subdomain+"_proj")
db.init_app(app)
db.create_all()
mail = Mail(app)
store = DictStore()
KVSessionExtension(store, app)
import proj.views
return app
I'm using Apache with mod_wsgi:
Apache Config
<VirtualHost *:80>
ServerName mywebsite.com
ServerAdmin admin#mywebsite.com
WSGIScriptAlias / /var/www/proj/app.wsgi
WSGIDaemonProcess application user=www-data group=www-data processes=5 threads=20
<Directory /var/www/proj/proj/>
Order allow,deny
Allow from all
</Directory>
#Alias /static /var/www/FlaskApp/FlaskApp/static
#<Directory /var/www/FlaskApp/FlaskApp/static/>
# Order allow,deny
# Allow from all
#</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
wsgi file
import sys
sys.path.insert(0, '/var/www/proj')
from subdomain import SubdomainDispatcher
from proj import create_app
application = SubdomainDispatcher(create_app)
Seems like some sort of race condition but I don't see where or why it would be happening. I've tried reducing the amount of processes and threads to 1 each but that also did not see to work.
Any advice is greatly appreciated as I've been struggling with this for awhile.
After a few other eyes took a look, the problem is that imports will only run once causing routes to only ever be associated to the first app created.
Essentially views are only ever instantiated once for the first app/subdomain hit.
The solution is instead of importing you have function in each module initializing the routes.
As so in views.py:
def init_views(app):
#app.route('/page')
def page():
return "asdf"
Thus each app has it's own copy of the routes instead of only the first.
What a doozy.

How can I generate URLs for uploaded files on my machine? (deployed Flask on Apache2 Debian)

In a Flask python function, I want to take a saved file and figure out the URL for it so I can input it into the Google Docs Viewer. So if I save 'test.pdf', it might return 'mydomain.com/www/html/myapp/packets/test.pdf'.
However I cannot figure out how to do this. It worked fine when I was in development, but broke since I deployed it. This is my apache2 config file.
<VirtualHost *:80>
DocumentRoot /var/www/html/myapp
ServerName mydomain.com
WSGIScriptAlias / /var/www/html/myapp/myapp.wsgi
<Directory /var/www>
Order deny,allow
Allow from all
</Directory>
ErrorLog /var/www/html/error.log
LogLevel info
CustomLog /var/www/html/access.log combined
</VirtualHost>
And my Python function (using AJAX to do the file upload):
#app.route('/uploadajax', methods=['POST', 'GET'])
def upload():
file = request.files['file']
if file and allowed_file(file.filename):
pkt_filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], pkt_filename))
return jsonify({'filename':'/var/www/html/myapp/packets/' + pkt_filename})
The problem is that I can't figure out where exactly mydomain.com is on the system. In development, I could just do mydomain.com/html/myapp/packets/test.pdf, and it would open in browser, but this doesn't work in deployment. Even though the DocumentRoot is /var/www/html/myapp, typing mydomain.com/packets/test.pdf into the address bar returns a 404 (even though it definitely exists on the system).
Another interesting thing is that os.cwd() in that Python function returns '/', although I'm not sure what the consequences of that are.
Any help?

Requested URL not found with mod_wsgi in Django

I am trying to get django to work on apache with mod_wsgi. My djang.wsgi code is:
import os, sys
sys.path.append('C:/djcode/mysite')
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
And my configuration in 'httpd' is:
Alias /static/ "C:/djcode/mysite/static/"
<Directory C:/djcode/mysite/static/>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / C:/djcode/mysite/apache/django.wsgi
<Directory C:/djcode/mysite/apache>
Order deny,allow
Allow from all
</Directory>
Alias /files/ "C:/djcode/mysite/files/"
<Directory C:/djcode/mysite/files/>
Order deny,allow
Allow from all
</Directory>
In the folder 'files' are files where I read data (not databases) which are used to output in templates.
The urls.py code is as follows:
urlpatterns = patterns('',
('^all/$', all),
('^(sport)/$', gen),
('^(teknology)/$', gen),
...
When I start Apache, localhost, the message is "It works!". But when I try localhost/all' or localhost/mysite or localhost/mysite/all, the browser says "The requested URL /all was not found on this server`. I can not understand where does it fail
Where is the definition or class for all? It's technically the controller. Can you post it?
This line routes it:
('^all/$', all)
But we don't know what all is.
Please make sure, you have the VirtualHost configuration correctly setup in the httpd.conf file. Try using localhost first (as the ServerName) and see if it works.

Categories