Auth
Authentication and level based authorization for PHP., (*1)
Installation
Install using composer, (*2)
composer require jasny\auth
Setup
Jasny\Auth
is an abstract class. You need to extend it and implement the abstract methods fetchUserById
and
fetchUserByUsername
. Also set the $secret
property to a randomly selected
string., (*3)
You also need to specify how the current user is persisted across requests. If you want to use normal PHP sessions, you
can simply use the Auth\Sessions
trait., (*4)
class Auth extends Jasny\Auth
{
use Auth\Sessions;
/**
* Secret word for creating a verification hash
* @var string
*/
protected static $secret = "A random string";
/**
* Fetch a user by ID
*
* @param int $id
* @return User
*/
public static function fetchUserById($id)
{
// Database action that fetches a User object
}
/**
* Fetch a user by username
*
* @param string $username
* @return User
*/
public static function fetchUserByUsername($username)
{
// Database action that fetches a User object
}
}
The fetch methods need to return a object that implements the Jasny\Auth\User
interface., (*5)
class User implements Jasny\Auth\User
{
/**
* Get the user ID
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Get the usermame
*
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Get the hashed password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Event called on login.
*
* @return boolean false cancels the login
*/
public function onLogin()
{
if (!$this->active) return false;
$this->last_login = new DateTime();
$this->save();
return true;
}
/**
* Event called on logout.
*/
public function onLogout()
{
$this->last_logout = new DateTime();
$this->save();
}
}
Authorization
By default the Auth
class only does authentication. Authorization can be added by impelmenting the authorize
method., (*6)
Two traits are predefined to do Authorization: Authz\byLevel
and Authz\byGroup
., (*7)
by level
The Authz\byLevel
traits implements authorization based on access levels. Each user get permissions for it's level and
all levels below., (*8)
class Auth extends Jasny\Auth implements Jasny\Auth\Authorization
{
use Jasny\Authz\byLevel;
/**
* Authorization levels
* @var array
*/
protected static $levels = [
1 => 'user',
10 => 'moderator',
20 => 'admin',
50 => 'superadmin'
];
}
For authorization the user object also needs to implement Jasny\Authz\User
, adding the hasRole()
method., (*9)
/**
* Check if the user has the specified security level
*
* @param int $level
* @return boolean
*/
public function hasRole($level)
{
return $this->security_level >= $level;
}
by group
The Auth\byGroup
traits implements authorization using access groups. An access group may supersede other groups., (*10)
class Auth extends Jasny\Auth implements Jasny\Auth\Authorization
{
use Jasny\Authz\byGroup;
/**
* Authorization groups and each group is supersedes.
* @var array
*/
protected static $groups = [
'users' => [],
'managers' => [],
'employees' => ['user'],
'developers' => ['employees'],
'paralegals' => ['employees'],
'lawyers' => ['paralegals'],
'lead-developers' => ['developers', 'managers'],
'firm-partners' => ['lawyers', 'managers']
];
}
For authorization the user object also needs to implement Jasny\Authz\User
, adding the hasRole()
method., (*11)
/**
* Check if the user is in the specified security group
*
* @param string $group
* @return boolean
*/
public function hasRole($group)
{
return in_array($group, Auth::expandGroup($this->group));
}
Usage
Authentication
Verify username and password, (*12)
Auth::verify($username, $password);
Login with username and password, (*13)
Auth::login($username, $password);
Set user without verification, (*14)
Auth::setUser($user);
Logout, (*15)
Auth::logout();
Get current user, (*16)
Auth::user();
Authorization
Check if user is allowed to do something, (*17)
if (!Auth::authorized('admin')) die("Not allowed");
Signup confirmation
Get a verification hash. Use it in an url and set that url in an e-mail to the user, (*18)
// Create a new $user
$confirmHash = generateConfirmationHash($user);
$url = 'http://' . $_SERVER['HTTP_HOST'] . '/confirm.php?hash=' . $hash;
// send email with $url to $user
Use the confirmation hash to fetch and verify the user, (*19)
// --- confirm.php
$user = Auth::fetchForConfirmation($_GET['hash']);
Forgot password
Forgot password works the same as the signup confirmation., (*20)
// Fetch $user by e-mail
$confirmHash = generatePasswordResetHash($user);
$url = 'http://' . $_SERVER['HTTP_HOST'] . '/reset.php?hash=' . $hash;
// send email with $url to $user
Use the confirmation hash to fetch and verify the user, (*21)
// --- reset.php
$user = Auth::fetchForPasswordReset($_GET['hash']);