Authentication, authorization and access control for PHP

Overview

jasny-banner

Jasny Auth

PHP Scrutinizer Code Quality Code Coverage Packagist Stable Version Packagist License

Authentication, authorization and access control for PHP.

Features


Installation

Install using composer

composer require jasny/auth

Usage

Auth is a composition class. It takes an authz, storage, and optionally a confirmation service.

use Jasny\Auth\Auth;
use Jasny\Auth\Authz\Levels;

$levels = new Levels(['user' => 1, 'moderator' => 10, 'admin' => 100]);
$auth = new Auth($levels, new AuthStorage());

session_start();
$auth->initialize();

// Later...
if (!$auth->is('admin')) {
    http_response_code(403);
    echo "Access denied";
    exit();
}

The Auth service isn't usable until it's initialized. This should be done after the session is started.

session_start();
$auth->initialize();

Documentation

Comments
  • ERROR : $hashedPassword must not be accessed before initialization in

    ERROR : $hashedPassword must not be accessed before initialization in

    Hi, Trying to use the library I got such an error.Where am I doing wrong? @jasny, @SergeAx, @Minstel

    Fatal error: Uncaught Error: Typed property Veloster\App\Models\User::$hashedPassword must not be accessed before initialization in C:\xampp\htdocs\php\App\Models\User.php:32
    Stack trace:
    #0 C:\xampp\htdocs\php\vendor\jasny\auth\src\Auth.php(319): Veloster\App\Models\User->verifyPassword('12345678')
    #1 C:\xampp\htdocs\php\App\Models\Accounts.php(46): Jasny\Auth\Auth->login('admin', '12345678')
    #2 C:\xampp\htdocs\php\App\Controllers\Home.php(27): Veloster\App\Models\Accounts->authenticate('admin', '12345678')
    #3 [internal function]: Veloster\App\Controllers\Home::login(
    #4 C:\xampp\htdocs\php\Core\Route.php(74): call_user_func_array(Array, Array)
    #5 C:\xampp\htdocs\php\index.php(24): Veloster\Core\Route::dispatch()
    #6 {main}
    thrown in C:\xampp\htdocs\php\App\Models\User.php on line 32
    

    User.php:

    <?php
    
    namespace Veloster\App\Models;
    
    use Jasny\Auth;
    use Jasny\Auth\UserInterface;
    
    class User implements UserInterface
    {
        public string $id;
        public string $username;
        public int $accessLevel = 0;
    
        protected string $hashedPassword;
    
        public function getAuthId(): string
        {
            return $this->id;
        }
    
        /**
         * {@interal This method isn't required by the interface}}.
         * @param string $password
         */
        public function changePassword(string $password): void
        {
            $this->hashedPassword = password_hash($password, PASSWORD_BCRYPT);
        }
    
        public function verifyPassword(string $password): bool
        {
            return password_verify($password, $this->hashedPassword);
        }
    
        public function getAuthChecksum(): string
        {
            return hash('sha256', $this->id . $this->hashedPassword);
        }
    
        public function getAuthRole(Auth\ContextInterface $context = null): int
        {
            return $this->accessLevel;
        }
    
        public function requiresMfa(): bool
        {
            return false;
        }
    }
    

    Funstion in Login_Controller.php:

    public function authenticate(string $username,string $password)
        {
            $levels = new Authz\Levels(['user' => 1, 'moderator' => 10, 'admin' => 100]);
    
            $auth = new Auth($levels, new AuthStorage());
    
            session_start();
            $auth->initialize();
            $auth->login($username,$password);
        }
    

    AuthStroge.php:

    <?php
    
    namespace Veloster\App\Models;
    
    use Jasny\Auth;
    use Illuminate\Database\Capsule\Manager as DB;
    use Jasny\Auth\StorageInterface;
    
    class AuthStorage implements StorageInterface
    {
        /**
         * Fetch a user by ID
         * @param string $id
         * @return Auth\UserInterface|null
         */
        public function fetchUserById(string $id): ?Auth\UserInterface
        {
            DB::table('Accounts')
                ->Where('id','=', $id)
                ->get();
            return new User();
        }
    
        /**
         * Fetch a user by username
         * @param string $username
         * @return Auth\UserInterface|null
         */
        public function fetchUserByUsername(string $username): ?Auth\UserInterface
        {
            DB::table('Accounts')->Where('username','=', $username)->get();
            return new User;
        }
    
        /**
         * Fetch the context by ID.
         * @param string $id
         * @return Auth\ContextInterface|null
         */
        public function fetchContext(string $id) : ?Auth\ContextInterface
        {
            DB::table('Accounts')
                ->Where('id','=', $id)
                ->get();
            return new Context();
        }
    
        /**
         * Get the default context of the user.
         * @param Auth\UserInterface $user
         * @return Auth\ContextInterface|null
         */
        public function getContextForUser(Auth\UserInterface $user) : ?Auth\ContextInterface
        {
            return null;
        }
    }
    
    opened by mertvoo 5
  • Incorrect third param in hash function in HashidsConfirmation.php

    Incorrect third param in hash function in HashidsConfirmation.php

    https://github.com/jasny/auth/blob/d8d0b723fec345c910ec415f0d338f54334c0082/src/Confirmation/HashidsConfirmation.php#L315

    Third param in hash function generates outputs raw binary data which trigger warnings in Hashids. In constructor of Hashids salt is encoding but is as binary so \mb_detect_encoding($salt) return incorrect encoding type for \mb_convert_encoding($salt, 'UTF-8', \mb_detect_encoding($salt))
    https://github.com/vinkla/hashids/blob/8cab111f78e0bd9c76953b082919fc9e251761be/src/Hashids.php#L95

    opened by ssulima 2
  • Non-static method Jasny\Auth\Auth::user() should not be called statically

    Non-static method Jasny\Auth\Auth::user() should not be called statically

    all of the mentioned methods in the documentation are called as static methods, but none of them is static so it gives an error

    Auth::login(string $username, string $password) Auth::loginAs(UserInterface $user) Auth::logout() ...etc

    invalid 
    opened by osamaAbdullah 1
  • Multi-factor authentication (MFA) support

    Multi-factor authentication (MFA) support

    The method of MFA shouldn't be important for this lib, though it would always include verifying some sort of code. Instead of requiring the use of wrapper, a callback that takes the user and code and returns a boolean should be all that's needed for the Auth class.

    In addition to the context, add bool $mfa as argument for getAuthRole(). This will be set to true if the user is MFA authenticated. It's up to the User class to return a role like 'mfa-required' if needed. Methods like isLoggedIn() will still return true, even if the login is just partial.

    To logic to setup MFA (like creating an OTP secret, sending an email, etc) is outside the scope of this library.

    If MFA fails the user is automatically logged out.

    class AuthController extends Jasny\Controller
    {
        public function run(...$args)
        {
            try {
                return parent::run(...$args);
            } catch (LoginException $exception) {
                $this->session->flash('warning', $exception->getMessage());
                $this->redirect('/login');
            }
        }
    
        public function postLogin()
        {
            $this->auth->login(
                $this->getQueryParam('username'),
                $this->getQueryParam('password'),
            );
    
            $next = $this->auth->is('mfa-required') ? '/login/mfa' : '/admin';
            $this->redirect($next);
        }
    
        public function postLoginMfa()
        {
            $this->auth->mfa($this->getQueryParam('code'));
            $this->redirect('/admin');
        }
    }
    
    class User
    {
        /** One time password secret for multi factor authentication (MFA) */
        public ?string $otpSecret = null;
    
        public getAuthRole(?ContextInterface $context, bool $mfa)
        {
            if ($this->otpSecret !== null && !$mfa) {
                return 'mfa-required';
            }
    
            return $this->role;
        }
    }
    
    $levels = new Authz\Levels([
        -1 => 'mfa-required',
        1 => 'user',
        20 => 'admin',
    ]);
    
    $auth = (new Auth($levels, ...))
        ->withMfa(static function(User $user, string $code): bool {
            return TOPT::create($user->otpSecret)->verify($code);
        });
    
    opened by jasny 1
  • Fatal error when trying to implement level based auth follow by example in README.md

    Fatal error when trying to implement level based auth follow by example in README.md

    Fatal error: gymadarasz\Auth\Auth and Jasny\Authz\byLevel define the same property ($levels) in the composition of gymadarasz\Auth\Auth. However, the definition differs and is considered incompatible. Class was composed in C:\xampp\htdocs\testauth\src\Auth\Auth.php on line 97

    My suugestion, just remove the line protected static $levels; from trait byLevel in file byLevel.php at line ~37

    opened by gymadarasz 1
  • Static function Jasny\Auth::fetchUserById() should not be abstract

    Static function Jasny\Auth::fetchUserById() should not be abstract

    While trying to implement the example in the README, I keep getting this error, I am using Slim and I am auto loading the example Auth class using composer's psr-0 like this "psr-0": { "": "auth/" }, is this probably because PHP doesn't support abstract static functions or am I doing things wrong?

    opened by PaulKish 1
  • Version 2

    Version 2

    PHP 7.4+

    Use composition instead of traits. PSR-15 Middleware (with double pass support). Changed API (big BC break).

    Get stateful Authz object (for current or other user / context). Give authz services an immutable state by caching the user role. Added recalc() methods.

    Support for context. This could an organization for instance. Check if the user has a role in that organization.

    Login/logout events via PSR-14 Event dispatcher (instead of methods on user).

    Renamed user and context methods to getAuthId(), so it doesn't clash with getId().

    Improved hashids confirmation (tokens not bc)

    opened by jasny 0
  • Authorization should not be done in User class

    Authorization should not be done in User class

    We should create an Authz class rather than moving that into the User class. Moving all functionality to a model class is a 'God object' anti-pattern.

    opened by jasny 0
  • Auth class shouldn't be static

    Auth class shouldn't be static

    While it is typical there is only one authentication interface per application, this is not the way by definition. Additionally using static methods and properties make testing harder.

    // Global Auth for an application
    App::auth();
    
    // Application instance for dependency injection
    $app->getAuth();
    
    opened by jasny 0
  • Verify bug fix, fetchByUsername may return false for invalid login, inst...

    Verify bug fix, fetchByUsername may return false for invalid login, inst...

    Verify bug fix, fetchByUsername may return false for invalid login, instead of empty model that implements the getPassword methods resulting in a fatal error. Verify should check for false and not presume fetchByUsername always returns user model.

    $user is always 'set' so the isset check is redundant

    opened by Turv 0
Releases(v2.2.0)
  • v2.2.0(Feb 8, 2021)

    Support Lcobucci JWT v4. The JWT class now takes the JWT configuration object as parameter instead of different services.

    The TokenConfirmation class generated a random token, which must be stored in the database.

    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Jan 31, 2021)

    Fix issue with generating a hashids salt. Hashids doesn't accept a binary string as salt, since the salt is converted to a UTF-8 string. In some cases the binary salt was working, but in other cases the mb_detect_encoding() method gave an error.

    When updating, please note that confirmation tokens created with v2.0 will not work with v2.1.

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta2(Dec 27, 2019)

    • Auth::user() throws an AuthException if not logged in.
    • Added method Auth::isLoggedIn().

    The user() method always returns a user and never null, as it typical to use Auth::user()->doSomething() while assuming a user is logged in due to access control on the page. Having the method return null is an issue when using static code analysis.

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-beta1(Dec 4, 2019)

  • v1.0.1(Dec 28, 2016)

  • v1.0.0(Dec 28, 2016)

Owner
Arnold Daniels
Web and blockchain developer at @ltonetwork
Arnold Daniels
An authorization library that supports access control models like ACL, RBAC, ABAC in Laravel.

Laravel Authorization Laravel-authz is an authorization library for the laravel framework. It's based on Casbin, an authorization library that support

PHP-Casbin 243 Jan 4, 2023
An authorization library that supports access control models like ACL, RBAC, ABAC for webman plugin

An authorization library that supports access control models like ACL, RBAC, ABAC for webman plugin

PHP-Casbin 18 Dec 30, 2022
GUI manager for RBAC (Role Base Access Control) Yii2. Easy to manage authorization of user

RBAC Manager for Yii 2 GUI manager for RBAC (Role Base Access Control) Yii2. Easy to manage authorization of user ?? . Documentation Important: If you

MDMunir Software 1.2k Jan 7, 2023
Authentication and authorization library for Codeigniter 4

Authentication and Authorization Library for CodeIgniter 4. This library provides an easy and simple way to create login, logout, and user registratio

Rizky Kurniawan 12 Oct 10, 2022
Slim Auth is an authorization and authentication library for the Slim Framework.

Slim Auth is an authorization and authentication library for the Slim Framework. Authentication is provided by the Zend Framework Zend\Authentication component, and authorization by the Zend Framework Zend\Permissions\Acl component.

Jeremy Kendall 246 Dec 16, 2022
A framework agnostic authentication & authorization system.

Sentinel Sentinel is a PHP 7.3+ framework agnostic fully-featured authentication & authorization system. It also provides additional features such as

Cartalyst 1.4k Dec 30, 2022
This is a basic Oauth2 authorization/authentication server implemented using Mezzio.

Mezzio-OAuth2-Authorization-Authentication-Server This is a basic OAuth2 authorization/authentication server implemented using Mezzio. I have found so

null 1 Nov 15, 2022
Tech-Admin is Laravel + Bootstrap Admin Panel With User Management And Access Control based on Roles and Permissions.

Tech-Admin | Laravel 8 + Bootstrap 4 Tech-Admin is Admin Panel With Preset of Roles, Permissions, ACL, User Management, Profile Management. Features M

TechTool India 39 Dec 23, 2022
Dynamic ACL is a package that handles Access Control Level on your Laravel Application.

Dynamic ACL Dynamic ACL is a package that handles Access Control Level on your Laravel Application. It's fast to running and simple to use. Install an

yasin 8 Jul 31, 2022
Register ,Login , Logout , having access control

Helo what's up dude read by the name of creator lov3yp :D This script is inspired by Lov3yp#2018 And Burak karahan Installation steps: !- Import the s

Lov3yp 2 Nov 1, 2021
Middleware to generate access logs for each request using the Apache's access log format

Middleware to generate access logs for each request using the Apache's access log format. This middleware requires a Psr log implementation, for example monolog.

Middlewares 20 Jun 23, 2022
It's a Laravel 8 authentication markdown that will help you to understand and grasp all the underlying functionality for Session and API Authentication

About Auth Starter It's a Laravel 8 authentication markdown that will help you to understand and grasp all the underlying functionality for Session an

Sami Alateya 10 Aug 3, 2022
Rinvex Authy is a simple wrapper for @Authy TOTP API, the best rated Two-Factor Authentication service for consumers, simplest 2fa Rest API for developers and a strong authentication platform for the enterprise.

Rinvex Authy Rinvex Authy is a simple wrapper for Authy TOTP API, the best rated Two-Factor Authentication service for consumers, simplest 2fa Rest AP

Rinvex 34 Feb 14, 2022
phpCAS is an authentication library that allows PHP applications to easily authenticate users via a Central Authentication Service (CAS) server.

phpCAS is an authentication library that allows PHP applications to easily authenticate users via a Central Authentication Service (CAS) server.

Apereo Foundation 780 Dec 24, 2022
Declarative style of authorization and validation in laravel.

Laravel Hey Man Readability Counts. In fact, Readability is the primary value of your code !!! ?? Heyman continues where the other role-permission pac

Iman 860 Jan 1, 2023
Files Course Laravel Micro Auth and Authorization

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

EspecializaTi 8 Oct 22, 2022
It's authorization form, login button handler and login to your personal account, logout button

Authorization-form It's authorization form, login button handler and login to your personal account, logout button Each file is: header.php - html-fil

Galina 2 Nov 2, 2021
EvaOAuth provides a standard interface for OAuth1.0(a) / OAuth2.0 client authorization, it is easy to integrate with any PHP project by very few lines code.

EvaOAuth EvaOAuth provides a standard interface for OAuth1.0 / OAuth2.0 client authorization, it is easy to integrate with any PHP project by very few

AlloVince 256 Nov 16, 2022