GithubHelp home page GithubHelp logo

zhorton34 / authorize-slim-4 Goto Github PK

View Code? Open in Web Editor NEW
86.0 7.0 45.0 4.59 MB

Slim 4 Authorization Tutorial

Home Page: https://www.youtube.com/playlist?list=PLNuh5_K9dfQ38pmas4Y3TEEHLMRkt9qh2

License: MIT License

PHP 0.21% Shell 0.01% JavaScript 97.09% Vue 0.01% CSS 2.65% SCSS 0.01% Blade 0.04%
php slim-framework slimphp slim slimconsole vuejs vue authentication slim4 slim-micro-framework

authorize-slim-4's Introduction

Twitter Follow Clean Code Studio

Authentication With Slim 4 (And much, much more)

Slim 4 Authentication Tutorial

Documentation Sections

Installation

Dependencies

  • Vagrant
  • VirtualBox or other available vagrant virtual machine provider
  1. Clone, enter, and determine the path the application
git clone https://github.com/zhorton34/authorize-slim-4.git

cd authorize-slim-4

pwd
  1. Copy output from pwd command (Full path to present working directory)

  2. Open authorize-slim-4/homestead.yaml and update folders map path (Has comment next to it below)

ip: 192.168.10.10
memory: 2048
cpus: 2
provider: virtualbox
authorize: ~/.ssh/id_rsa.pub
keys:
    - ~/.ssh/id_rsa
folders:
    -
       # Replace `map: /Users/zhorton/tutorials/authorize-slim-4`
       # With `map: {the_copied_output_from_pwd_in_step_2}
        map: /Users/zhorton/tutorials/authorize-slim-4
        ## map Update with path you cloned the repository on your machine
        to: /home/vagrant/code
sites:
    -
        map: slim.auth
        to: /home/vagrant/code/public
databases:
    - slim
features:
    -
        mariadb: false
    -
        ohmyzsh: false
    -
        webdriver: false
name: authorize-slim-4
hostname: authorize-slim-4
  1. Save and close homestead.yaml

  2. Run vagrant up --provision to boot up your virtual machine

  3. Once booted, open up your localmachine's host file (sudo vim /etc/hosts on linux or mac)

  4. Add slim.auth

  5. Boot up the vagrant virtual

  vagrant up --provision
  1. Open your localmachines host file (sudo vim /etc/hosts on linux and mac)

  2. Add slim.auth and the ip defined in the homestead.yaml (Example below, shouldn't need to change from example)

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1	localhost
255.255.255.255	broadcasthost
::1             localhost

###########################
# Homestead Sites (Slim 4)
###########################
192.168.10.10   slim.auth
  1. Close and save hosts file

  2. Test out http://slim.auth/ in your browser (Make sure vagrant has properly finished booting from step 8)

  3. cd back into authorize-slim-4 within your terminal

  4. Run vagrant ssh

  5. Once ssh'd into your virtual machine, run

cd code && cp .env.example .env && composer install && npm install

===

List Slim Console Commands

  1. Run php slim from project root
sole Tool

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  help              Displays help for a command
  list              Lists commands
  tinker            
 db
  db:fresh          Drop all database table and re-migrate, then re-seed all tables
  db:migrate        Migration migrations to database
  db:seed           Run Database Seeders
  db:show           Show all of your models/table records in a table for display
 error-logs
  error-logs:clear  Remove Errors Logs Rendered Templates
 make
  make:command      Generate Command Scaffold
  make:controller   description text for console command
  make:factory      Scaffold new factory command
  make:middleware   Generate or make Scaffold for new http middleware class
  make:migration    Make or scaffolded new migration for our database
  make:model        Generate The Scaffold For An Eloquent Model
  make:provider     Scaffold new Service Provider
  make:request      Generate Form Request Validation Scaffold
  make:seeder       Generate a database seeder scaffold
  make:event        Generate event scaffold
  make:listener     Generate listener scaffold
  make:trait        Create a new trait
  make:view         Generate view Scaffold
 migrate
  migrate:rollback  Rollback Previous Database Migration
 view
  view:clear        Remove Cache For View Templates

Migrate and Seed Database

  1. vagrant ssh
  2. cd code
  3. php slim db:migrate
  4. php slim db:seed

Show database table example

  1. vagrant ssh
  2. cd code
  3. php slim db:show users

Register Middleware

  1. Create Middleware Class (Example: \App\Http\Middleware\RouteGuardMiddleware::class)
  2. Open authorize-slim-4/app/Http/HttpKernel
  3. Add \App\Http\Middleware\RouteGuardMiddleware::class to a specific route group or globally
class HttpKernel extends Kernel
{
    /**
     * Global Middleware
     *
     * @var array
     */
    public array $middleware = [
//        Middleware\ExampleAfterMiddleware::class,
//        Middleware\ExampleBeforeMiddleware::class
    ];

    /**
     * Route Group Middleware
     */
    public array $middlewareGroups = [
        'api' => [],
        'web' => [
            Middleware\RouteContextMiddleware::class,
            'csrf'
        ]
    ];
}

Create and Register new php slim command

  1. Add new ExampleCommand.php File and class at app/console/commands/ExampleCommand.php
  2. Define Command name, description, arguments, and handler within class
class ExampleCommand extends Command
{
    protected $name = 'example:command';
    protected $help = 'Example Command For Readme';
    protected $description = 'Example Command For Readme';

    public function arguments()
    {
        return [
            'hello' => $this->required('Description for this required command argument'),
            'world' => $this-optional('Description for this optional command argument', 'default')
        ];
    }

    public function handler()
    {
        /** Collect Console Input **/
        $all_arguments = $this->input->getArguments();
        $optional_argument = $this-input->getArgument('world');
        $required_argument = $this->input->getArgument('hello');

        /** Write Console Output **/
        $this->warning("warning output format");
        $this->info("Success output format");
        $this->comment("Comment output format");
        $this->error("Uh oh output format");
    }
}
  1. Open app\console\ConsoleKernel.php
  2. Add ExampleCommand::class to Registered Commands
<?php

namespace App\Console;

use Boot\Foundation\ConsoleKernel as Kernel;

class ConsoleKernel extends Kernel
{
    public array $commands = [
        Commands\ExampleCommand::class, // Registered example command
        Commands\ViewClearCommand::class,
        Commands\MakeSeederCommand::class,
        Commands\DatabaseRunSeeders::class,
        Commands\DatabaseFreshCommand::class,
        Commands\MakeMigrationCommand::class,
        Commands\DatabaseMigrateCommand::class,
        Commands\DatabaseTableDisplayCommand::class,
        Commands\DatabaseRollbackMigrationCommand::class
    ];
}

php slim make:{command} Scaffold Stub Generators

  1. Available Generator Commands
  php slim make:command {ExampleConsoleCommand}      Generate Command Scaffold
  php slim make:controller {Example} description text for console command
  php slim make:factory {ExampleFactory}      Scaffold new factory command
  php slim make:middleware {ExampleMiddleware} Generate or make Scaffold for new http middleware class
  php slim make:migration {CreateExamplesTable   Make or scaffolded new migration for our database
  php slim make:model {Example}        Generate The Scaffold For An Eloquent Model
  php slim make:provider {ExampleServiceProvider}     Scaffold new Service Provider
  php slim make:request {ExampleFormRequest}     Generate Form Request Validation Scaffold
  php slim make:seeder {ExamplesTableSeeder}       Generate a database seeder scaffold
  1. Scaffold Generator Stubs (Dummy Files)

    • resources/stubs
  2. Scaffold Configuration

    • config/stubs.php

Global Helper Functions

/*

  • event
  • old
  • back
  • session
  • validator
  • asset
  • redirect
  • collect
  • factory
  • env
  • base_path
  • config_path
  • resources_path
  • public_path
  • routes_path
  • storage_path
  • app_path
  • dd (die and dump)
  • throw_when
  • class_basename
  • config
  • data_get
  • data_set */

old($input_name)

  • Used within blade to populate old input data when form validation fails

Example

<form>
  @csrf
  <input type='text' name='first_name' value='{{ old('first_name') }}' />
</form>

back()

  • Redirect user back to previous page

Example

ExampleController 
{
   index()
   {
      return back();
   }
}

event()

  • Set up events and event listeners
event()->listen('flash.success', fn ($message) => session()->flash()->add('success', $message);

event()->fire('flash.success', ['Way to go, it worked!']);

Alternatively, you can use the slim scaffold to set up event and listener classes php slim make:event ExampleEvent

  • creates App/Events/ExampleEvent php slim make:listener ExampleListener
  • create App/Listeners/ExampleListener

Register Class Event & Listeners in config/events.php

return [
   'events' => [
      ExampleEvent::class => [
          ExampleListener::class,
          ExampleListenerTwo::class,
          ExampleListenerThree::class
      ],
      ResetUserPasswordEvent::class => [
          GenerateResetPasswordKey::class,
          SendUserResetPasswordEmail::class,
      ]
   ]
];

Finally trigger the associated event

// Fire event using dependency injection
event()->fire(ExampleEvent::class);

// Fire event overriding default depency injections
event()->fire(ExampleEvent::class, [
   // parameterOne
   // parameterTwo
]);

session()

  • Session (Using Syfony Session Component)

Example

// Flash to session to only remember for the proceeding request
session()->flash()->set('success', ['Successful Form Submission!']);
session()->flash()->set('errors', ['Name field failed', 'Email field failed']);

// Set directly to session to remember for several requests
session()->set('remember_in_session_for_multiple_requests', ['remember me']);

validator($input, $rules = [], $messages = [])

  • Validator (Using Laravel Validators)

Example

$input = [
   'first_name' => 'John',
   'last_name' => 'Joe',
   'email' => '[email protected]'
];

$rules = [
   'first_name' => 'required|string',
   'last_name' => 'required|string|max:50',
   'email' => 'required|email|max:50|unique:users,email'
];

$messages = [
    'first_name.required' => 'First name is a required field',
    'first_name.string' => 'First name must be a string field',
    'last_name.required' => 'Last name must is a required field',
    'last_name.string' => 'Last name must be a string field',
    'email.email' => 'Email must be in the proper email format',
    'email.unique' => 'Email already taken, no duplicate emails allowed',
    'email.required' => 'Email is required',
];

$validation = validator($input, $rules, $messages);

if ($validation->fails()) {
   session()->flash()->set('errors', $validation->errors()->getMessages());
   
   return back();
}

if ($validation->passes() {
   session()->flash()->set('success', 'Successfully Submitted Form and Passed Validation');

   return redirect('/home');
}

Mailables (Send Emails)

  1. @see \Boot\Foundation\Mail\Mailable Example
class ExampleController
{
   public function send(\Boot\Foundation\Mail\Mailable $mail, $response)
   {
       $user = \App\User::first();
       
       $success = $mail->view('mail.auth.reset', ['url' => 'https://google.com'])
            ->to($user->email, $user->first_name)
            ->from('[email protected]', 'Slim Authentication Admin')
            ->subject('Reset Password')
            ->send();

       $response->getBody()->write("Successfully sent Email: {$success}");

       return $response;
   }
}

Events (Events & associated listeners with dependency injection)

Example One

  • Set up events and event listeners using the global event helper function NOTE: (This example show's an easy setup, but example two is considered better architecture)
// App\Providers\EventServiceProvider boot method()

event()->listen('flash.success', fn ($message) => session()->flash()->add('success', $message);

event()->fire('flash.success', [
   'Way to go, it worked!'
]);

Example Two: Event & Listener Classes

  1. php slim make:event UserLogin
  2. Open App/Events/UserLogin.php
  3. Use the UserLogin.php event __construct to build or "construct" the event payload
<?php

namespace App\Events;

use App\Support\Auth;
use Boot\Foundation\Http\Session;

class ExampleEvent
{
    public $user;
    public $session;

    public function __construct(Session $session)
    {
        $this->user = Auth::user();
        $this->session = $session;

        return $this;
    }
}
  1. php slim make:listener FlashWelcomeBackMessage
  2. Open App/Listeners/FlashWelcomeBackMessage
  3. Handle the event payload in the Listener __invoke method
<?php

namespace App\Listeners;

use App\Events\UserLogin;

class FlashWelcomeBackMessage
{
   public function __invoke(UserLogin $event)
   {
      $event->session->flash()->add('success', "Welcome Back {$event->user->first_name}!"); 
   }

}

Register Class Event & Listeners in config/events.php

return [
   'events' => [
      UserLogin::class => [
          FlashWelcomeBackMessage::class,
          // ExampleListenerTwo::class,
          // ExampleListenerThree::class
      ],
      // ResetUserPasswordEvent::class => [
           // GenerateResetPasswordKey::class,
           // SendUserResetPasswordEmail::class,
      // ]
   ]
];

Finally trigger event (Example: App\Http\Controllers\LoginController@login)

public function login(StoreLoginRequest $input)
{
  if ($input->failed()) return back(); 

  if (Auth::attempt($input->email, $input->password)) 
  {
      event()->fire(\App\Events\UserLogin::class); // Fire Event

      return redirect('/home');
   }

   return back();
}

Event Constructor and Listener Invoke Methods Support Dependency Injection // App\Http\LoginController@login

// Example Using UserLogin Event:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$session = app()->resolve('session');
$different_user = \App\User::find(5); 

event()->fire(UserLogin::class, [
   $session, $different_user
]);

// Example Using Random Event
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
event()->fire(ExampleEvent::class, [
   // parameterOne
   // parameterTwo
]);

// Dependency Injection With While Using event() to register listeners
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
event()->listen('welcome-view', fn (\Jessengers\Blade\Blade $blade) => $blade->make('welcome')->render());

// Fire's event. Listeners will work using the blade instance resolved from our service container
event()->fire('welcome-view');

// inject blade instance with different template path than the one binded to our container
event()->fire('welcome-view', [
    new \Jessengers\Blade\Blade(
        base_path('vendor/package/resources/views'), 
        storage_path('cache'),
    )
]);


Packages & Resources Glossary

authorize-slim-4's People

Contributors

dependabot[bot] avatar iajohn avatar zhorton34 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

authorize-slim-4's Issues

php slim db:migration gives no error, but tables are not getting created

Hi,
The skeleton is extremely well developed, I like the structure and implementation and your explanation in the video tutorials.

But I am getting this issue.

I use PHP 8, so, I removed faker, php from the require dependencies.
I dont use homebrew.
I created a DB from mysql command.
Then after changing the env file with required db name, user, password, host as localhost (tried with 127.0.0.1 also)

php slim db:migration exectues and results is green

Screenshot 2021-10-13 at 5 22 01 PM

But php slim db:show users gives

Screenshot 2021-10-13 at 5 23 06 PM

Connection refused! not sure how!

Kindly help me with this.

PHP-DI Error thrown because of RequestInput constructor

I've traced this error down to the Bootstrapper LoadDebuggingPage.php shown below (because if I comment out line 20 it will run).

10    class LoadDebuggingPage extends Bootstrapper
11    {
12        public function boot()
13        {
    ...
19            $blade = $this->app->resolve(Blade::class);
20            $input = ($this->app->resolve(RequestInput::class))->all();
21            //$input = [];

RequestInput class:

class RequestInput
{
    protected array $meta;
    protected array $attributes;

    public function __construct($request, $route)
    {
    ...

Error Thrown:

Fatal error: Uncaught DI\Definition\Exception\InvalidDefinition:
    Entry "App\Support\RequestInput" cannot be resolved: Parameter $request of __construct() has no value defined or guessable
            Full definition:  Object (
              class = App\Support\RequestInput
              lazy = false
              __construct(
                $request = #UNDEFINED#
                $route = #UNDEFINED#
              )
            )
            in app\vendor\php-di\php-di\src\Definition\Exception\InvalidDefinition.php:19
Stack trace:
#0 app\vendor\php-di\php-di\src\Definition\Resolver\ObjectCreator.php(156): DI\Definition\Exception\InvalidDefinition::create(Object(DI\Definition\ObjectDefinition), 'Entry "app\\...')
#1 app\vendor\php-di\php-di\src\Definition\Resolver\ObjectCreator.php(71): DI\Definition\Resolver\ObjectCreator->createInstance(Object(DI\Definition\ObjectDefinition), Array)
#2 app\vendor\php-di\php-di\ in app\vendor\php-di\php-di\src\Definition\Exception\InvalidDefinition.php on line 19

I assume a more recent update of PHP-DI library is the cause. Assistance would be greatly appreciated.

I've tried various imports and type hints, but not sure the solution:

use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Routing\Route;

Password Encryption Strategy

  • Update Password Encryption Strategy

Currently we are storing sha1 hash of the password.
Then, on login, we are comparing the hash of the submitted password with the database column.

This isn't a good idea because unsalted hashes are vulnerable to rainbow tables, and sha1 is not a good choice because it's a fast hash.

PHP has good built-in functions that handle this securely, here is some info:

https://phptherightway.com/#password_hashing https://paragonie.com/blog/2017/12/2018-guide-building-secure-php-software#secure-php-passwords

Routes and methods not found

Hi
I think the only thing missing in this project are the error pages, for when the route (404) or method is not found.

Any idea?
Thanks

First `vagrant up --provision` fails

Missing PHP vendor folder on first run.

$ vagrant up --provision
Vagrant failed to initialize at a very early stage:

There was an error loading a Vagrantfile. The file being loaded
and the error message are shown below. This is usually caused by
a syntax error.

Path: /home/X/Projects/authorize-slim-4/Vagrantfile
Line number: 0
Message: LoadError: cannot load such file -- /home/X/Projects/authorize-slim-4/vendor/laravel/homestead/scripts/homestead.rb

Does this means that I need to install PHP in the host machine to use composer, then run the development machine and then remove PHP from the host system?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.