#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    71
    Rep Power
    11

    Assigning session ID


    Hi.
    Your help is highly appreciated.
    I'm building web app, using apache.
    As it looks, I'll need to build the session-cookie mechanism manualy.
    Is there any way (alghorithm?) to make sure that the session ID that are
    generated by the server are unique ?! ( even between server restarts ?)

    Thank you very much
    Roy
  2. #2
  3. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    I surpose the best way to do this is to get the current time and multiply it by a random number. But i dout there's really any garentee when it comes to session ID's or rather... you can't be too safe.

    Code:
    >>> import time, random
    >>> '%08d' % int(time.time() * random.randint(0, 1000000) % 100000000)
    '11086810'
    >>>
    I surpose you're best bet would be to check if the session ID exists when creating it but without knowing exactly how you plan to use the sessions and how its hard to sugest how you can do this.

    Hope this helps,

    Mark.
    programming language development: www.netytan.com Hula

  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    71
    Rep Power
    11
    Originally Posted by netytan
    I surpose the best way to do this is to get the current time and multiply it by a random number. But i dout there's really any garentee when it comes to session ID's or rather... you can't be too safe.

    Code:
    >>> import time, random
    >>> '%08d' % int(time.time() * random.randint(0, 1000000) % 100000000)
    '11086810'
    >>>
    I surpose you're best bet would be to check if the session ID exists when creating it but without knowing exactly how you plan to use the sessions and how its hard to sugest how you can do this.

    Hope this helps,

    Mark.

    Hi Mark.
    Thanks for your reply.
    What I intend to do, is for each user , to assign a cookie that contains it's session ID.
    One scenario, is:
    1. The session on the server is deleted (expired)
    2. New user comes is , and he is assigned with a new session ID (which
    ,let's say, equivalent to the previouse one.
    3. Now, we have two users, with the same session ID stored in their cookies

    Hope it explains the problem better,
    roy
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    London, England
    Posts
    1,585
    Rep Power
    1373
    there are several possible solutions.

    for total overkill, you can create a GUID, which are 128 bit numbers guaranteed to be unique throughout the known universe by combining the MAC address, timestamp, process ID, and some random bits. If you are running on Windows and have the Win32 extensions installed you can get a GUID by calling pythoncom.CreateGuid(). On some unix systems there is a command to generate a GUID, which you could call from Python.

    As I say, this is probably overkill, since your ID only needs to be unique on your server.

    Two alternatives spring to mind:

    If you are using a database you can set up a counter field which you increment for each session. The database transaction code will make sure that no two sessions get given the same number. However accessing the database is not very efficient, unless it is something you need to do each session anyway.

    My favourite solution would be to generate an ID by concatenating the current time and a random number, e.g.

    Code:
    import time, random
    >>> id = hex(int(time.time()*1000))[2:] + '-' + hex(random.randint(0, 0x7FFFFFFF))[2:]
    >>> id
    'FAD281E0D3L-38784d3c'
    >>>
    using this technique there is a one in two billion chance that if two users connect in the same millisecond then they will both get the same ID. Theoretically possible, but not likely enough to lose sleep over.

    Dave - The Developers' Coach
  8. #5
  9. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    Very nice post , informtive and the ID generator was awesum. Interesting though, will the numbre always appear the same length or vary?

    I surposed you could be sure by storing a list of active/possibly active current IDs and do a search for the ID before creating the new ID but with a 1 in 2 billion chance

    Mark.
    programming language development: www.netytan.com Hula

  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    71
    Rep Power
    11
    Originally Posted by netytan
    I surpose the best way to do this is to get the current time and multiply it by a random number. But i dout there's really any garentee when it comes to session ID's or rather... you can't be too safe.

    Code:
    >>> import time, random
    >>> '%08d' % int(time.time() * random.randint(0, 1000000) % 100000000)
    '11086810'
    >>>
    I surpose you're best bet would be to check if the session ID exists when creating it but without knowing exactly how you plan to use the sessions and how its hard to sugest how you can do this.

    Hope this helps,

    Mark.

    Hi Mark.
    Thanks for your reply and solution.
    I'll use it, and the time combined with the cpu ticks, will guarentee uniqueness.
    Thanks a lot.
    Roy
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    71
    Rep Power
    11
    Originally Posted by DevCoach
    there are several possible solutions.

    for total overkill, you can create a GUID, which are 128 bit numbers guaranteed to be unique throughout the known universe by combining the MAC address, timestamp, process ID, and some random bits. If you are running on Windows and have the Win32 extensions installed you can get a GUID by calling pythoncom.CreateGuid(). On some unix systems there is a command to generate a GUID, which you could call from Python.

    As I say, this is probably overkill, since your ID only needs to be unique on your server.

    Two alternatives spring to mind:

    If you are using a database you can set up a counter field which you increment for each session. The database transaction code will make sure that no two sessions get given the same number. However accessing the database is not very efficient, unless it is something you need to do each session anyway.

    My favourite solution would be to generate an ID by concatenating the current time and a random number, e.g.

    Code:
    import time, random
    >>> id = hex(int(time.time()*1000))[2:] + '-' + hex(random.randint(0, 0x7FFFFFFF))[2:]
    >>> id
    'FAD281E0D3L-38784d3c'
    >>>
    using this technique there is a one in two billion chance that if two users connect in the same millisecond then they will both get the same ID. Theoretically possible, but not likely enough to lose sleep over.

    Dave - The Developers' Coach

    Hi Dave.
    That's a brilliant solution.
    Thank you very much
    Roy
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Posts
    624
    Rep Power
    34
    I see the "one obvious solution" (Apart from using one of the multiple existing, tested sessioning implementations ) as: Store a session id integer on the server, and for each session id, increment it by one.

    - The code is simple and readable.
    - There is no chance, during normal operation, that two people will get the same ID. Not even if they connect in the same millisecond and hit a billion to one long-shot.
    - One addition has to be more efficient than a time call, a random call, two hex conversions, one int conversion, two string slices and two string concatenations.
    - Since Python implicitly supports BigIntegers, it's never going to wrap around either - at a thousand connections per millisecond for a hundred years you only count to 3153600000000000 - not exactly a memory hog either.

    So, what am I missing?
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    London, England
    Posts
    1,585
    Rep Power
    1373
    I think it depends on your environment and requirements. If you are writing a CGI script then it is not an option, since a new python process will be started for each page access. If you are using a long running service, e.g. Zope, Webware, mod_python etc then it may be a viable option (but I think Zope and Webware will take care of the session ID for you anyway).

    Even with a long running process there is still a problem with having an in-memory counter if you want the session ID to be unique across server restarts. Here is an example of where it may be a problem: imagine you have a shopping cart system, and user A logs in and is given a session ID. he browses your site and adds a few items to the cart. At some point your web service dies and is automatically restarted. Your user is oblivious of this and carries on shopping. In the meantime user B has logged on and now has the same session ID, since the count was reset when the server restarted. A and B are now adding items to the same shopping cart, with the potential for all sorts of nastiness.

    To get round this you would need to save the ID on the server each time - I originally suggested using a record in a database, since that will handle all the transaction logic for you. You could write it to a file, but then you have a potential issue of two processes or threads writing to the same file at once. You can work round it, but it very quickly becomes more complex (and less efficient) than the time+random solution.

    One possible compromise would be to have a file holding a count of the server restarts, and concatenate that with an in-memory counter. Something like this (untested code ahead - caveat emptor):

    Code:
    #When the service starts:
    restartCount = int(open('serverCount.txt', 'r').read()) + 1
    open('serverCount.txt', 'w').write(str(restartCount))
    sessionCount = 0
    
    #when assigning a session ID
    sessionID = '%s:%s' % (restartCount, sessionCount)
    sessionCount += 1
    If your server uses threads to handle requests then you may still need to add a thread lock around the code that assigns the session ID.

    I suspect that in practice the most common solution is to use a database record - if you have a shopping cart or similar then you will be making heavy use of a database anyway.

    Dave - The Developers' Coach
  18. #10
  19. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    Another possible problem here is if somone desided to play silly beggers and incement/decrement there session ID. On busy web sites chances are that the session ID before or after your's will still be active and then as Dave said...

    A and B are now adding items to the same shopping cart, with the potential for all sorts of nastiness.
    Correct me if i'm wrong,

    Mark.
    programming language development: www.netytan.com Hula

  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Posts
    624
    Rep Power
    34
    Good points indeed. I hadn't at all considered the security/hacking side of it.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    3
    Rep Power
    0

    Lightbulb unique id


    In php I always use something like:

    Code:
    from md5 import md5
    from random import random
    from time import time
    
    UserName="JohnDoe"
    unique = md5(UserName + str(time()) + "secretstring" + str(random())).hexdigest()
    print unique
    The idea is: IF the same user is logging in at the same time and gets the same random number he will get the same md5 :-) Nothin to worry about, methinks.

IMN logo majestic logo threadwatch logo seochat tools logo