怎样在 Laravel 中处理前端认证
在Laravel中我们可以很方便的通过策略(Policy)来进行权限认证问题。一个简单的例子如下:
<?php
namespace App\Policies;
use App\User;
use App\Post;
class PostPolicy
{
/**
* 判断该方法能否被用户操作。
*
* @param \App\User $user
* @param \App\Post $post
* @return bool
*/
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
}
上面的代码表示只有当前登录的用户ID和发表文章的用户ID一致时,才可以编辑文章。而在blade模版中可以像下面的代码一样使用:
@can('update', $post)
<button>Edit</button>
@endcan
这样我们就完成了一个简单的权限处理。但是当我们使用Vue等前端框架处理的时候,我们没有办法使用can方法,所以,处理方式就比较麻烦了起来,下面的几种方法是我在Laracasts和FREEK.DEV上看到的解决办法。
下面的几个方法均假设我们已经把文章抽离成了一个Vue组件叫做blog-post
.
方法一
将对应的权限传递到组件中。
<blog-post :post="{{ $post }}" :canUpdate="@json(auth()->user()->can('update', $post))"></blog-post>
我们在组件内部可以通过v-if来判断是否显示Edit按钮
<button v-if="canUpdate">Edit</button>
方法二
将对应的权限包含到post数据中返回给前端
<?php
namespace App;
class Post extents Model
{
protected $appends = ['authorizations'];
public function getAuthorizationsAttribute()
{
return [
'update' => \Gate::allows('update', $this),
'destroy' => \Gate::allows('destroy', $this),
];
}
}
在前端中我们可以直接获取post中的数据来处理权限问题
<button v-if="post.authorizations.update">Edit</button>
方法三
将相关的权限存储到数据库中。首先在users表中加入字段permissions,在这里保存权限信息,简单的demo如下:
$user->permissions = ["update-post", "destroy-post"];
$user->save();
针对复杂的情况可以用到多对多的数据库关系来储存(实际上就是我们经常用到的权限系统),然后在我们的blade模版顶部显示出权限信息。
<script>
window.App = {
permissions: @json(auth()->user()->permissions)
}
</script>
在Vue中我们通过window.App.permissions
来进行权限处理。
方法四
与方法二很相似,只不过将getAuthorizationsAttribute
替换成了API资源来进行处理,具体的内容可以查看文章底部的第二个链接。
讨论
就我个人而言,由于前后端分离,我一般使用的是第二种或者是第四种方法。不知道你们碰到这种情况会怎样处理呢?
参考
- Frontend Authorization Brainstorming
- How to handle front-end authorization using Laravel, Inertia and TypeScript
本作品采用《CC 协议》,转载必须注明作者和本文链接
目前我的做法是登录时将该用户所有权限返回给前端存储,自行实现前端鉴权逻辑。
@jenkincei 万一权限有变化,你这个还需要重新登录进行处理吧。(或者其他的方法)