concept of session and cookie in web development python
Question: I am very new to web development, i am working on `web.py` framework to
develop a small web application. suppose the login screen is
`localhost:9090/login`, after the succesfull login it is redirecting to next
page `localhost:9090/details` and after clicking another button `add` its
again redirecting to `localhost:9090/details/details_entry`.

But when i tried directly `localhost:9090/details`on browser its working and
able to see the page without even logged in . So after googling a lot came to
know that i need to use `session concept` , but i am tired as of now for busy
schedule on searching about web concepts in google. Can anyone let me know the
concept of

  1. `session` (Actually why it is created and how to use it after login through page in python)

  2. Actually whats the complete concept of `user authentication` , What are the steps to follow to create a user login page And steps to follow after user logged in with details what happens when user logouts and how to session code in python

I expect what ever the language it is but the concept of developing login
screen and redirecting to next url by creating some sessions ids is same, so
the user authentication concept is very important and may be this question is
useful to others.

**Edited Code**

**\--------------**

**Login.py**

    
    
    import os
    import sys
    import web
    from web import form
    
    
    
    render = web.template.render('templates/')
    
    
    urls = (
      '/',   'Login',
      '/projects',  'Projects',
      '/project_details',  'Project_Details',  
    )
    
    app = web.application(urls, globals())
    
    
    web.config.debug = False
    db = web.database(dbn='mysql', db='Python_Web', user='root', pw='redhat')
    settings = {}
    store = web.session.DBStore(db, 'sessions')
    session = web.session.Session(app, store, initializer={'user': None})
    
    class Login:
    
        login_form = form.Form( 
            form.Textbox('username', form.notnull),
            form.Password('password', form.notnull),
            form.Button('Login'),
            )
    
        def GET(self):
            form = self.login_form()
            return render.login(form)
    
    def POST(self):
        if not self.login_form.validates():
            return render.login(self.login_form)
        i = web.input()
        username = i.username
        password = i.password
        user = db.select('user',
            where = 'user_login = $username', 
            vars = {'username': username}
        if username == user['username'] and password == user['password']:
            session.user = username
            raise web.seeother('/projects')
    
        else:
            return render.login_error(form)    
    
    def auth_required(func):
        def proxyfunc(self, *args, **kw):
            print session.user,"=======> Session stored"
            try:
                if session.user:
                  return func(self, *args, **kw)
            except:
                pass
            raise web.seeother("/")
        return proxyfunc
    
    class Projects:
    
        project_list = form.Form( 
            form.Button('Add Project'),
            )
    
        @auth_required
        def GET(self):
            project_form = self.project_list()
            return render.projects(project_form)  
    
       def POST(self):
            raise web.seeother('/project_details')
    
    if __name__ == "__main__":
        web.internalerror = web.debugerror
        app.run()  
    

In the above code after successfull login the page is redirecting to next
page. Here i need to implement session concept, but i was stuck on where to
implement session code in the above code. Can anyone please point me to a
right way on where to write session code in the above py code for login page.
After this worked need to implement logout functionality in the same py file

Edited code after implementing `auth_required` function and got the below
error

**Result:**

    
    
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/web/application.py", line 239, in process
        return self.handle()
      File "/usr/lib/python2.7/site-packages/web/application.py", line 230, in handle
        return self._delegate(fn, self.fvars, args)
      File "/usr/lib/python2.7/site-packages/web/application.py", line 420, in _delegate
        return handle_class(cls)
      File "/usr/lib/python2.7/site-packages/web/application.py", line 396, in handle_class
        return tocall(*args)
      File "/home/local/user/python_webcode/index.py", line 102, in proxyfunc
        print session.user,"=======> Session Stored"
      File "/usr/lib/python2.7/site-packages/web/session.py", line 71, in __getattr__
        return getattr(self._data, name)
    AttributeError: 'ThreadedDict' object has no attribute 'user'
    


Answer: web.py provides [session](http://webpy.org/cookbook/sessions) abstraction and
several session stores. What you have to do, is to write login controller,
display the form on GET, and find user and perform password check on POST,
then store the user in session and kill the session on logout. After it you
may write decorator that checks if user exists in session to use it over
controller methods. Anyway, user authentication concept is mostly the same in
all web apps.

If you need already working solution for web.py then you may take a look at
this module: <http://jpscaletti.com/webpy_auth/>

If you decided to implement login youself, the simplest auth decorator will
probably look like this:

    
    
    def auth_required(func):
        def proxyfunc(self, *args, **kw):
            try:
                if session.user:
                  # user is logged in
                  return func(self, *args, **kw)
            except:
                pass
            # user is not logged in
            raise web.seeother("/login")
        return proxyfunc
    

Then you will be able to use @auth_required before your GET and POST methods
in controllers like this:

    
    
    class Projects:
        @auth_required
        def GET(self):
            pass
    

