慕容的工作随笔

慕容的工作随笔

记录学习和工作

【原创】Laravel中的权限系统

中间件

Laravel 内置了一些中间件,例如身份验证、CSRF 保护等。所有的中间件都存放在 app/Http/Middleware 文件夹中。

<?php

namespace App\Http\Controllers;

class UsersController extends Controller
{
public function __construct()
{
$this->middleware('auth', [
'except' => ['show', 'create', 'store']
]);
}
}

middleware 方法接收两个参数,第一个是中间件的名称,第二个是要进行过滤的动作。 except 方法用来设定指定动作不使用 Auth 中间件进行过滤,即除了此处指定的动作以外,所有其他动作都必须登录用户才能访问,类似于黑名单的过滤机制。 only 方法只过滤指定动作。

在控制器 Auth 中间件使用中,首选 except 方法,这样的话,当新增一个控制器方法时,默认是安全的,此为最佳实践。

授权策略

创建授权策略

php artisan make:policy UserPolicy

所有生成的授权策略文件都会被放置在 app/Policies 文件夹下。 app/Policies/UserPolicy.php

<?php

namespace App\Policies;

use Illuminate\Auth\Access\HandlesAuthorization;
use App\Models\User;

class UserPolicy
{
use HandlesAuthorization;

public function update(User $currentUser, User $user)
{
    return $currentUser-&gt;id === $user-&gt;id;
}

}

注册授权策略

Laravel 提供两种注册授权策略的方式,第一种是手动指定,第二种是自动授权注册。自动授权注册如下:

app/Providers/AuthServiceProvider.php

<?php

namespace App\Providers;

class AuthServiceProvider extends ServiceProvider
{
.
.
.
public function boot()
{
$this->registerPolicies();
// 修改策略自动发现的逻辑
Gate::guessPolicyNamesUsing(function ($modelClass) {
// 动态返回模型对应的策略名称,如:// 'App\Models\User' => 'App\Policies\UserPolicy',
return 'App\Policies\'.class_basename($modelClass).'Policy';
});
}
}

授权策略定义完成之后,便可以在控制器中使用 authorize 方法来验证用户授权策略。默认的 App\Http\Controllers\Controller 类包含了 Laravel 的 AuthorizesRequests trait。此 trait 提供了 authorize 方法,它可以被用于快速授权一个指定的行为,当无权限运行该行为时会抛出 HttpException。authorize 方法接收两个参数,第一个为授权策略的名称,第二个为进行授权验证的数据。

引用:

<?php

namespace App\Http\Controllers;

class UsersController extends Controller
{

public function edit(User $user)
{
    $this-&gt;authorize(&#039;update&#039;, $user);
    return view(&#039;users.edit&#039;, compact(&#039;user&#039;));
}

public function update(User $user, Request $request)
{
    $this-&gt;authorize(&#039;update&#039;, $user);
    $this-&gt;validate($request, [
        &#039;name&#039; =&gt; &#039;required|max:50&#039;,
        &#039;password&#039; =&gt; &#039;nullable|confirmed|min:6&#039;
    ]);

    $data = [];
    $data[&#039;name&#039;] = $request-&gt;name;
    if ($request-&gt;password) {
        $data[&#039;password&#039;] = bcrypt($request-&gt;password);
    }
    $user-&gt;update($data);

    session()-&gt;flash(&#039;success&#039;, &#039;个人资料更新成功!&#039;);

    return redirect()-&gt;route(&#039;users.show&#039;, $user);
}

}

友好的重定向

重定向到用户登录之前访问的页面:

<?php

namespace App\Http\Controllers;

class SessionsController extends Controller
{
public function store(Request $request)
{
$credentials = $this->validate($request, [
'email' => 'required|email|max:255',
'password' => 'required'
]);

   if (Auth::attempt($credentials, $request-&gt;has(&#039;remember&#039;))) {
       session()-&gt;flash(&#039;success&#039;, &#039;欢迎回来!&#039;);
       $fallback = route(&#039;users.show&#039;, Auth::user());
       return redirect()-&gt;intended($fallback);
   } else {
       session()-&gt;flash(&#039;danger&#039;, &#039;很抱歉,您的邮箱和密码不匹配&#039;);
       return redirect()-&gt;back()-&gt;withInput();
   }
}
.
.
.

}

redirect() 的 intended 方法可将页面重定向到上一次请求尝试访问的页面上,并接收一个默认跳转地址参数,当上一次请求记录为空时,跳转到默认地址上。

注册与登录页面访问限制

只让未登录用户访问登录页面:

<?php

namespace App\Http\Controllers;

class SessionsController extends Controller
{
public function __construct()
{
$this->middleware('guest', [
'only' => ['create']
]);
}
}

只让未登录用户访问注册页面:

<?php

namespace App\Http\Controllers;
class UsersController extends Controller
{
public function __construct()
{
$this->middleware('auth', [
'except' => ['show', 'create', 'store']
]);

    $this-&gt;middleware(&#039;guest&#039;, [
        &#039;only&#039; =&gt; [&#039;create&#039;]
    ]);
}

}

app/Http/Middleware/RedirectIfAuthenticated.php

<?php

class RedirectIfAuthenticated
{

public function handle(Request $request, Closure $next, ...$guards)
{
    $guards = empty($guards) ? [null] : $guards;

    foreach ($guards as $guard) {
        if (Auth::guard($guard)-&gt;check()) {
            session()-&gt;flash(&#039;info&#039;, &#039;您已登录,无需再次操作。&#039;);
            return redirect(RouteServiceProvider::HOME);
        }
    }

    return $next($request);
}

}

}

app/Providers/RouteServiceProvider.php

class RouteServiceProvider extends ServiceProvider
{
    /**
     * The path to the "home" route for your application.
     *
     * This is used by Laravel authentication to redirect users after login.
     *
     * @var string
     */
    public const HOME = '/';

评论 (0)

还没有评论,来做第一个吧。

发表评论

提交后需管理员审核通过后显示