1. Trang chủ
  2. » Công Nghệ Thông Tin

Tạo mạng xã hội với PHP - part 9 doc

10 255 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Users, Registration, And Authentication
Trường học University of Information Technology
Chuyên ngành Computer Science
Thể loại Tài liệu
Năm xuất bản 2010
Thành phố Jacksonville
Định dạng
Số trang 10
Dung lượng 3,39 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

At their core, users can be represented by a few simple pieces of information: • A unique identifier such as a user ID • A unique identifier that the user themselves can easily remember,

Trang 1

Privacy policies

When users sign up to any website, they generally agree to the terms and conditions

of the website, and the privacy policy While the terms and conditions generally set

out information about liability, conduct on the site, and so on, the privacy policy

explains what will be done with the users' data

It is important to be clear and honest with users about their data, and reassuring

about the security of their data Facebook has had a lot of bad press recently relating

to its privacy policy and the tools available to their users to protect their data In

particular, one of their recent changes resulted in a document that was over 5,800

words long—something that most users won't read or understand (http://www

huffingtonpost.com/2010/05/12/facebook-privacy-policy-s_n_574389

html) When stating your privacy policies:

• Be clear and concise

• Make it clear who can access the data they add to the site:

° Are all profiles public?

° How much information is available to what type of user?

° How can the information be restricted?

• Explain who owns the data—does the user retain ownership or do they grant

a licence of use to us?

It is also important for us to think about how we might allow users to change their

own privacy settings, including which profile information they would like to make

public, public only to their network, or completely private—particularly with

regards to contact details and dates of birth

Some countries also have legislation in place governing the management of user

data, such as the Data Protection Act in the UK This covers issues such as:

• Security—ensuring data is held securely, and isn't easy for others to access,

unless the user's permission has been given

• Relevancy—ensuring data held is kept up to date and is relevant

• Removal—allowing users to request full removal of their data

• Access—allowing users to request copies of all data held about them

Trang 2

At their core, users can be represented by a few simple pieces of information:

• A unique identifier such as a user ID

• A unique identifier that the user themselves can easily remember, such as

their chosen username or their e-mail address

• A password, which is used to authenticate the user—to prove they are who

they say they are

As far as our authentication system is concerned, this will be a user We will of

course extend this with a user profile, but in terms of authentication, this is all the

information we need

Our user object

Our user object is created when a user tries to log in, either based on submitting

a login form supplying their username and password, or based on session data

for the user ID

If username and password are supplied, then it checks the credentials and populates

its variables if such a user exists If only an ID is supplied, then it populates based on

whether there is a user of that ID Since the authentication class controls whether the

current user is logged in or not, we can use this object to view or perform actions on

other users if we wished, as by separating the two we won't be automatically logged

in as the user populated within this object As a result, we can extend this object to

reset the user's password, edit the user, deactivate the user, and so on

The constructor takes four arguments, the registry (dependency injection, so it

can communicate with the rest of the framework), a user ID, a username, and a

password, the latter three being optional, and used as described above

public function construct( Registry $registry, $id=0,

$username='', $password='' )

{

$this->registry = $registry;

If we haven't set a user ID (that is, $id is 0) and we have set a username and a

password, we should look up the user to see whether these are valid credentials:

if( $id=0 && $username != '' && $password != '' )

{

$user = $this->registry->getObject('db')-

>sanitizeData( $username );

Trang 3

As our passwords are hashed in the database, we need to hash the password we

were supplied We can hash the password directly in the query (by using the MySQL

function MD5), however, this exposes the password in plain text more than required,

as it would be processed and accessed by both PHP and the MySQL server

(which may be stored on a remote machine):

$hash = md5( $password );

$sql = "SELECT * FROM users WHERE username='{$user}' AND

password_hash='{$hash}' AND deleted=0";

$this->registry->getObject('db')->executeQuery( $sql );

if( $this->registry->getObject('db')->numRows() == 1 )

{

We have a record in the database, so the user is valid, so we set the various

properties of our user object:

$data = $this->registry->getObject('db')->getRows();

$this->id = $data['ID'];

$this->username = $data['username'];

$this->active = $data['active'];

$this->banned = $data['banned'];

$this->admin = $data['admin'];

$this->email = $data['email'];

$this->pwd_reset_key = $data['pwd_reset_key'];

$this->valid = true;

}

}

elseif( $id > 0 )

{

If we supplied a user ID, then we look up the user with that ID and populate the

object with their details As discussed above, we don't want to set them as logged-in

here, because we may use this object to edit, delete, and create users, and integrating

authentication would log out the administrator and log them in as someone else if

they tried to edit an existing user

$id = intval( $id );

$sql = "SELECT * FROM users WHERE ID='{$id}' AND deleted=0";

$this->registry->getObject('db')->executeQuery( $sql );

if( $this->registry->getObject('db')->numRows() == 1 )

{

$data = $this->registry->getObject('db')->getRows();

$this->id = $data['ID'];

$this->username = $data['username'];

$this->active = $data['active'];

Trang 4

$this->admin = $data['admin'];

$this->email = $data['email'];

$this->pwd_reset_key = $data['pwd_reset_key'];

$this->valid = true;

}

}

}

Our authentication registry object

One of the first things our framework needs to do, once it is connected to the

database, and some core settings are loaded, is to check whether the current user

is logged in This is simply done by checking for an active session, and if one exists,

building the user object from that, or checking to see if a username and password

have been supplied, and building the user from that

This will make up part of our authentication object (registry/authentication

class.php), which will reside in our registry and interact with the user object

The checkForAuthentication method checks both for an active session and user

credentials being passed in POST data, and calls additional methods to build the

user object if appropriate

public function checkForAuthentication()

{

Initially, we remove any error template tags on the page (which we would use to

inform the user of an invalid login):

$this->registry->getObject('template')->getPage()-

>addTag('error', '');

if( isset( $_SESSION['sn_auth_session_uid'] ) && intval( $_

SESSION['sn_auth_session_uid'] ) > 0 )

{

If session data is set, we call the sessionAuthenticate method:

$this->sessionAuthenticate( intval( $_SESSION['sn_auth_

session_uid'] ) );

Trang 5

The sessionAuthenticate method then sets the loggedIn property to indicate

whether the user is logged in or not:

if( $this->loggedIn == true )

{

$this->registry->getObject('template')->getPage()-

>addTag('error', '');

}

else

{

If the user is not logged in, and we have a valid session, then something went wrong

somewhere, so we should inform the user their login attempt was not successful:

$this->registry->getObject('template')->getPage()-

>addTag('error', '<p><strong>Error: Your username or

password was not correct,

please try again</p><strong>');

}

}

If session data was not set, we check for post data, and call the postAuthenticate

method if appropriate, following the same steps as above

elseif( isset( $_POST['sn_auth_user'] ) &&

$_POST['sn_auth_user'] != '' && isset(

$_POST['sn_auth_pass'] ) && $_POST['sn_auth_pass'] != '')

{

$this->postAuthenticate( $_POST['sn_auth_user'] , $_

POST['sn_auth_pass'] );

if( $this->loggedIn == true )

{

$this->registry->getObject('template')->getPage()-

>addTag('error', '');

}

else

{

$this->registry->getObject('template')->getPage()-

>addTag('error', '<p><strong>Error: Your username or

password was not correct,

please try again</p><strong>');

}

}

elseif( isset( $_POST['login']) )

Trang 6

If the login post variable has been set, but neither session data or POST login data

has been submitted, then the user didn't enter a username or a password, so we

should tell them this:

$this->registry->getObject('template')->getPage()-

>addTag('error', '<p><strong>Error:

Your must enter a username and a password</p><strong>');

}

}

This method also sets suitable template tag variables for standard errors if there was

a problem authenticating the user

POST authentication

In the code above, if the user has tried to log in by submitting a login form, the

postAuthenticate method is called This method is shown below It utilizes the

user object to query the database, if the user exists and is logged in, then it sets the

appropriate session data, as highlighted below:

private function postAuthenticate( $u, $p )

{

$this->justProcessed = true;

require_once(FRAMEWORK_PATH.'registry/user.class.php');

$this->user = new User( $this->registry, 0, $u, $p );

if( $this->user->isValid() )

{

if( $this->user->isActive() == false )

{

$this->loggedIn = false;

$this->loginFailureReason = 'inactive';

}

elseif( $this->user->isBanned() == true )

{

$this->loggedIn = false;

$this->loginFailureReason = 'banned';

}

else

{

$this->loggedIn = true;

$_SESSION['sn_auth_session_uid'] =

>getUserID();

}

Trang 7

}

else

{

$this->loggedIn = false;

$this->loginFailureReason = 'invalidcredentials';

}

}

SESSION authentication

If the user hasn't tried to log in by submitting a form, but has some session data set,

we try and authenticate them based on the session data:

private function sessionAuthenticate( $uid )

{

require_once(FRAMEWORK_PATH.'registry/user.class.php');

$this->user = new User( $this->registry, intval( $_SESSION['sn_

auth_session_uid'] ), '', '' );

if( $this->user->isValid() )

{

if( $this->user->isActive() == false )

{

$this->loggedIn = false;

$this->loginFailureReason = 'inactive';

}

elseif( $this->user->isBanned() == true )

{

$this->loggedIn = false;

$this->loginFailureReason = 'banned';

}

else

{

$this->loggedIn = true;

}

}

else

{

$this->loggedIn = false;

$this->loginFailureReason = 'nouser';

}

if( $this->loggedIn == false )

{

$this->logout();

}

Trang 8

Salt your passwords!

Our passwords are stored in the database as an MD5 one-way hash

This means we don't keep a copy of the user's password; instead, we

hash the password when they try to log in, and compare the hash to

the password in the database If our database was compromised, our

users' passwords should be safe This hashing cannot be reversed, but

there are dictionaries available for common words or phrases, which

means it is possible to work out some passwords from the hashes We

can prevent this further by salting the password; this involves adding

a "salt" to the password and then hashing it This is typically done by

creating a random string for each user and storing it in their row in the

users table Passwords in the Dino Space code are currently not salted,

to make it easier should you wish to change how the passwords are

hashed, or integrate with other login systems

Structuring the database

For our users table (without social profile data), we need the following fields:

Field Type Description

Key, Auto-increment The unique user ID

Password_salt Varchar(5) If we decide to salt our passwords

administrator or not

banned

when the user forgets it Reset_expires Timestamp Time at which that reset string expires—

preventing someone spamming a user by constantly requesting a new key

Trang 9

We currently have two primary database tables for our users A users table,

containing the core user data, and a users_profile table, containing other

(non-essential) information

Standard details

Our core registration fields are defined in our registration controller; they

are stored as array pairs, referencing the field name with a more descriptive

name (the more descriptive name is used for error messages)

/**

* Standard registration fields

*/

private $fields = array( 'user' => 'username', 'password' =>

'password', 'password_confirm' => 'password confirmation',

'email' => 'email address');

/**

* Any errors in the registration

*/

private $registrationErrors = array();

/**

* Array of error label classes - allows us to make a field a

different color, to indicate there were errors

*/

private $registrationErrorLabels = array();

/**

* The values the user has submitted when registering

*/

private $submittedValues = array();

/**

* The santized versions of the values the user has submitted -

these are database ready

*/

private $sanitizedValues = array();

/**

* Should our users automatically be "active" or should they

require email verification?

Trang 10

private $activeValue = 1;

private function checkRegistration()

{

We set an allClear variable, to indicate that the values submitted are all acceptable

Each time an error is encountered, this is set to false, so that we can report the error

back to the user:

$allClear = true;

The first stage is to check whether the user has actually submitted all of the required

fields, if any of them are blank, then we flag these errors to the user

// blank fields

foreach( $this->fields as $field => $name )

{

if( ! isset( $_POST[ 'register_' $field ] ) ||

$_POST[ 'register_' $field ] == '' )

{

If any are blank, our allClear variable is set to false, and we generate error strings,

and store them in our errors array:

$allClear = false;

$this->registrationErrors[] = 'You must enter a ' $name;

$this->registrationErrorLabels['register_' $field '_

label'] = 'error';

}

}

Next, we can check the values in more detail Let's start with the password!

We will want the password to be at least seven characters, to help ensure it is secure

To prevent issues of a user not knowing their password because they entered it

incorrectly, we ask the user to verify their password, so we must also check the

password and its verification match:

// passwords match

if( $_POST[ 'register_password' ]!= $_POST[ 'register_password_

confirm' ] )

{

$allClear = false;

$this->registrationErrors[] = 'You must confirm your

password';

$this->registrationErrorLabels['register_password_label'] =

'error';

$this->registrationErrorLabels['register_password_confirm_

label'] = 'error';

Ngày đăng: 04/07/2014, 21:20

TỪ KHÓA LIÊN QUAN

w