Start

Permission design is a very important function of background management, so to design well. PHP already has a lot of these packages so we don’t have to reinvent the wheel. Of course, you can start from scratch if you want


PS

The way that does authority attestation has several kinds before, I say commonly used two kinds!

  1. Each page authenticates the currently required permissions once
  2. Validate the model ER diagram of a database with a simple table structure that only holds important information in a unified place (middleware)

    (PS: In this design, users do not have permissions directly, but can only inherit permissions through roles. There are a lot ofpackagesWill provide users with direct access to the function)

Model

Model association relation processing:

  1. The User model

      

namespace App\Models;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;
	
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password'.'remember_token',];// Model relationships between users and roles
    public function roles(a)
    {
        return $this->belongsToMany(Role::class);
    }
	
	/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * encapsulates a method convenient use * 1. Required permissions * 2. Traverses all roles owned by the current user * 3. Through role permission to judge whether there is the need to * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
	public function hasPermission($permissionName)
	{
		foreach ($this->roles as $role) {
			if ($role->permisssions()->where('name', $permissionName)->exists()) {
				return true;; }}return false; }}Copy the code
  1. Role model
<? php namespace App\Models; Class Role extends Model {class Role extends Model {publicfunction users()
    {
        return $this->belongsToMany(User::class); } // Model association of roles and permissions publicfunction permissions()
    {
        return $this->belongsToMany(Permission::class); }}Copy the code
  1. Permission model
<? php namespace App\Models; Class Permission extends Model {// The Model relation between a role and a Permission publicfunction roles()
    {
        return $this->belongsToMany(Role::class); }}Copy the code

Database Seed

  • Insert some records:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# users:
+-------+---------+-----------+
| id    | name    |  password |
+-----------------+-----------+
|   1   |  gps    |  123456   |
+-----------------+-----------+
|   2   |  david  |  123456   |
+-----------------+-----------+
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# roles:
+-------+---------+
| id    | name    |
+-----------------+
|   1   |  admin  |
+-----------------+
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# permissions:
+-------+-----------------+
| id    |       name      |
+-------------------------+
|   1   | create_product  |
|   2   | delete_product  |
+-------------------------+
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# role_user (user GPS has admin role identity)
+---------+---------+
| role_id | user_id |
+---------+---------+
|   1     |   1     |
+------------------+
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# permission_role (the admin role has permission to create and delete items)
+---------+---------------+
| role_id | permission_id |
+---------+---------------+
|   1     |      1        |
|   1     |      2        |
+-------------------------+
Copy the code

First

The first kind of introduction:

<? php namespace App\Http\Controllers; use App\Models\Product; class ProductsController extends Controller { publicfunction store(Request $request) {// Check whether the current logged-in user has permissionsif (! $request->user()->hasPermission('create_product')) { abort(403); } / /do something
		
        return back()->with('status'.'Added item succeeded');
    }


    public function destroy(Product $product) {// Check whether the current logged-in user has permissionsif (! $request->user()->hasPermission('delete_product')) { abort(403); } / /do something
		
        return back()->with('status'.'Deleted item succeeded'); }}Copy the code

Two

As can be seen from the above code, even if the authorization verification code is encapsulated, it still needs to be verified in different ways, and the scalability is not high. In this case, we only need to add a field in the authorization table to solve the problem

1. Permissions (Add a route field, if not used in Laravel, Can add a url Field matching) + -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- - + + -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name | varchar(191) | NO | | NULL | | | route | varchar(191) | NO | | NULL | | + -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- - + + -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + 2. When I insert the data, We just be related to the entry + -- -- -- -- -- -- -- + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + | | id name | route | +-------------------------+------------------+ | 1 | create_product | products.store | | 2 | delete_product | products.destroy | +-------------------------+------------------+Copy the code

When we add the data, we don’t need to validate in the controller anymore, we just need to create a new middleware.

<? php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Route; use App\Models\Permission; Class PermissionAuth {/** * puts the middleware into the routing group and the routes that need to be validated into the intermediate group */ publicfunction handle($request, Closure $next) {/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * alias for current routing, if there is no return null * (not in laravel when using, You can get the current url) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /$route= Route::currentRouteName(); // Check whether the route in the permission table needs authenticationif ($permission = Permission::where('route'.$route)->first()) {// The current user does not have the name of this permissionif (! auth()->user()->hasPermission($permission->name)) {
                return response()->view('errors.403'['status'= >"Insufficient permissions, need: {$permission- > name} permission"]); }}return $next($request); }}Copy the code

END

If used in laravel, which already has wheels, please use github.com/spatie/lara…