Question

I have a little problem with web.py. Exacly I have problem with sessions.

Link to my app: http://len.iem.pw.edu.pl/~witkowr1/apps/demo/

Login/password: wtq/wtq

Code:

    # -*- coding: utf-8 -*- 
import web 
import json
from web.contrib.template import render_jinja
import datetime

prefix = '/~witkowr1/apps/demo'

urls = (
    prefix + '/login','Login',
    prefix + '/logout','Logout',
    prefix + '/', 'Index',
)

app = web.application(urls, globals())
wsgi = app.wsgifunc()
session = web.session.Session(app, web.session.DiskStore('sessions'),initializer={'time':datetime.datetime.now()})
render = render_jinja('static', encoding = 'utf-8')
render._lookup.globals.update(assets=prefix+'/static')

class Login:
    def GET(self):
    web.seeother(prefix+'/')

    def POST(self):
        login = web.input().login
    password = web.input().passwd
    if login == 'wtq' and password == 'wtq':
            session.logged_in = True
            session.time = datetime.datetime.now()
            last_login = web.cookies().get('time')
            if last_login == None:
                last_login_data = u'Zalogowałeś się pierwszy raz.'
            else:
                last_login_data = last_login
        return render.logged(name=login, date_last_login=last_login_data)
        else:
            session.logged_in = False
        error=u'Niepoprawne dane. SprĂłbuj jeszcze raz.'
            return render.login(error_msg=error)

class Logout:
    def GET(self):
        web.seeother(prefix+'/')

    def POST(self):
        session.logged_in = False
        web.setcookie('time',session.time)
        message = u'Zostałeś poprawnie wylogowany.'
        session.kill()
        return render.login(error_msg=message)

class Index:
    def GET(self):
        return render.login()

if __name__ == "__main__":
    app.run()

I would like to verify session and if I login early, I see site with latest login date. Now, when I refresh the site, I must login again. I think, that I check session, when I rendering HTML site, but I don't know, what I do it.

Please help!

Was it helpful?

Solution 3

I solved my problem. Very stupid mistakes :)

Code:

# -*- coding: utf-8 -*- 
import web 
from web.contrib.template import render_jinja
import datetime

prefix = ''

urls = (
    prefix + '/', 'Index',
    prefix + '/login','Login',
    prefix + '/logout','Logout',
)

app = web.application(urls, globals())
wsgi = app.wsgifunc()
web.config.debug = False
session = web.session.Session(app, web.session.DiskStore('sessions'),initializer={'time':datetime.datetime.now()})
render = render_jinja('static', encoding = 'utf-8')
render._lookup.globals.update(assets=prefix+'/static')

allowed = (
    ('user','user'),
)

class Login:

    def GET(self):
        web.seeother(prefix+'/')

    def POST(self):
        login = web.input().login
        passwd = web.input().passwd
        if(login,passwd) in allowed:
            session.logged_in = True
        session.login = login
            session.time = datetime.datetime.now()
            last_login = web.cookies().get('time')
            if last_login == None:
                last_login_data = u'Zalogowałeś się pierwszy raz.'
            else:
                last_login_data = last_login
            return render.logged(name=login, date_last_login = last_login_data)
        else:
            session.logged_in = False
        error=u'Niepoprawne dane. Spróbuj jeszcze raz.'
            return render.login(error_msg=error)

class Logout:
    def GET(self):
        web.seeother(prefix+'/')

    def POST(self):
        session.logged_in = False
        web.setcookie('time',session.time)
        message = u'Zostałeś poprawnie wylogowany.'
        session.kill()
        return render.login(error_msg=message)

class Index:
    def GET(self):
        if session.get ('logged_in') == True: 
            last_login = web.cookies().get('time')
            if last_login == None:
                last_login_data = u'Zalogowałeś się pierwszy raz.'
            else:
                last_login_data = last_login
            return render.logged(name=session.get ('login'), date_last_login = last_login_data)
    else:
            return render.login()

if __name__ == "__main__":
    app.run()

OTHER TIPS

The problem here is that you are not checking whether they are logged in if they access the page with GET method.

You would need to make a change like:

def GET(self):
    if session.logged_in:
        last_login = web.cookies().get('time')
        if last_login == None:
            last_login_data = u'Zalogowałeś się pierwszy raz.'
        else:
            last_login_data = last_login
        return render.logged(name=login, date_last_login=last_login_data)
    else:
        web.seeother(prefix+'/')

But you should rewrite this, a lot, so that you are taken to another page once you are logged in, and that page is responsible for rendering this information. There is a lot of room for improvement in the structure of your application.

That said, the simple answer is - even though you store the session, the "GET" method of login is entirely unaware of sessions, and will always return the login prompt.

Not sure if you solved your problem already but since it looks like there are often some problems with sessions in web.py I pushed a small and crude demo of it to bitbucket. Works fine for me so hope this works for you.

You can get it via:

git clone https://victorkohler@bitbucket.org/victorkohler/webpy-login.git

This is not an answer to your question but an extension of the question. I have a similar solution to the login from the webpy cookbook (http://webpy.org/cookbook/userauthbasic) but would like to load the variable allowed from a database.

allowed = (
    ('user','user'),
)

When I tried a read to assign the value to the variable it comes out as "None" when executed in the login class.

def readUsersDb(): 
    def POST(self):
        # load user data into allowed variable
        usersDbFilePath = 'userdata/irf/default/'
        usersDbFile = 'usersDb.db'
        usersDbFilePath = usersDbFilePath + usersDbFile

        conn = sqlite3.connect(usersDbFilePath)
        c = conn.cursor()

        c.execute('SELECT * FROM users')
        output = c.fetchall()
        conn.close()
        global allowed
        allowed = output
readUsersDb()

The login functions when the variable allowed is hard coded. I used the format from the database read and it still functions as expected so it is not a format issue.

#response: [(u'user1', 'user1'), (u'user2', 'user2'), (u'user3', 'user3')]

Hopefully someone has tried to do this previously. If it is a faux pas to add a question as an answer I apologize ahead of time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top