Asked  7 Months ago    Answers:  5   Viewed   40 times

I have been simply writing 2 cookies, 1 containing the user ID, and the 2nd containing 1/2 the SH1 hash of the password (salted). The way it works is self-evident.

I realized that I wasnt doing this in the most secure way. Whats a better way of doing this? Preferably using a single authentication cookie.

Also, is there a point to using "hard to calculate hashes"? By that I mean, using bcrypt, or hashing each item 10,000 times with whirlpool, to make it a (relatively) slow hash function (200 ms vs less than 1 ms just plain SHA1)? I mean if someone breaches your DB and gets the hashes.... what is there left to protect, since all your data is in the same DB (Unless you have some sort of a de-centralized setup, which I dont).

 Answers

72

use Sessions. Store the session id in the cookie, and store the state of the user on the server side (loggedIn, userId, IP).

To clarify what you need to store in the session array:

  • loggedIn: A boolean variable about whether the user is logged in or not. You reuse the same cookie for multiple sessions, so you remember the users username next time they come to your site, etc.
  • userId: The uniqe id of the user in the database. Use this to get more information on the user, like username, email etc. This too can be kept in the session array after the user logs out.
  • IP: To prevent someone from stealing the session id and using it, you store the IP of the user as well. This is optional, as sometimes you want to allow the user to roam (eg, stackoverflow allows me to move about with my laptop without logging me out when the IP changes).
  • lastPing: The timestamp the user was last seen. This can be used instead of the cookie expiration date. If you also store the lifetime of the session, then you can log the user out due to inactivity. This means that the session id cookie can be stored on the users computer for a very long time.

When the user logs out or is logged out due to inactivity, you simply set loggedIn to false. When the user logs in with the right username and password you set loggedIn to true and update the other fields (userId, IP, lifetime). When the user loads a page, you check the lastPing against the current time and the lifetime, and either update lastPing or logout the user.

The session data can either be stored in the filesystem or in a database. If stored in a database, then userId is either a foreign key to the user record, or all the data can be put in the user record.

Hashing

rehashing a value several times is not a good idea, because you reduce the security. Instead use salt, combining a static salt (name of the page for example) and the username of the user, together with the password. A hash that takes a long time isn't better than a fast hash, a hash that results in a large digest is better than a hash that results in a short digest (due to brute force). Using SHA1 should be good enough for a normal site (IE, not a bank or a secret military organization).

Wednesday, March 31, 2021
 
tpow
answered 7 Months ago
77

Generally, the first is better for reasons other people have stated here already.

However, if you need to store data on a class privately, but the footprint of data members is unknown, you'll often see your 2nd example combined with __get() __set() hooks to hide that they're being stored privately.

class someThing {

    private $data = array();

    public function __get( $property )
    {
        if ( isset( $this->data[$property] ) )
        {
            return $this->data[$property];
        }
        return null;
    }

    public function __set( $property, $value )
    {
        $this->data[$property] = $value;
    }
}

Then, objects of this class can be used like an instance of stdClass, only none of the members you set are actually public

$o = new someThing()
$o->cow = 'moo';
$o->dog = 'woof';
// etc

This technique has its uses, but be aware that __get() and __set() are on the order of 10-12 times slower than setting public properties directly.

Saturday, May 29, 2021
 
zhartaunik
answered 5 Months ago
61

When you ask the Auth class to attempt a login, you pass in the username and pass as it is. But if you look into the method, it will first hash the password to make it secure and then match it with database entry. When you are storing it, from your present implementation, its not hashed.

As suggested above, you should make this change in your seeder:

array(
    'username' => 'admin',
    'password' => Hash::make('password')
),

Although I am not very sure if the way you are using seeder is correct by syntax, but if it works, just hash the password there.

Saturday, May 29, 2021
 
DCD
answered 5 Months ago
DCD
53

@Sean beat me to it, nice job :-)

If you remove the action="dest.php" it should work. Right now you are sending the form to a page that does not check the values of the username and password, thus the session variable is not set.

<form method="post">
Username: <input type="text" name="user"/>
....
</form>
Saturday, May 29, 2021
 
laurent
answered 5 Months ago
44

I'd probably do something like this:

<?php

class Student
{
    public function __construct() {
        // allocate your stuff
    }

    public static function withID( $id ) {
        $instance = new self();
        $instance->loadByID( $id );
        return $instance;
    }

    public static function withRow( array $row ) {
        $instance = new self();
        $instance->fill( $row );
        return $instance;
    }

    protected function loadByID( $id ) {
        // do query
        $row = my_awesome_db_access_stuff( $id );
        $this->fill( $row );
    }

    protected function fill( array $row ) {
        // fill all properties from array
    }
}

?>

Then if i want a Student where i know the ID:

$student = Student::withID( $id );

Or if i have an array of the db row:

$student = Student::withRow( $row );

Technically you're not building multiple constructors, just static helper methods, but you get to avoid a lot of spaghetti code in the constructor this way.

Monday, June 7, 2021
 
The_Perfect_Username
answered 5 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :