怎样在Laravel中处理前端认证

在Laravel中我们可以很方便的通过策略(Policy)来进行权限认证问题。一个简单的例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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模版中可以像下面的代码一样使用:

1
2
3
@can('update', $post)
<button>Edit</button>
@endcan

这样我们就完成了一个简单的权限处理。但是当我们使用Vue等前端框架处理的时候,我们没有办法使用can方法,所以,处理方式就比较麻烦了起来,下面的几种方法是我在LaracastsFREEK.DEV上看到的解决办法。

下面的几个方法均假设我们已经把文章抽离成了一个Vue组件叫做blog-post.

方法一

将对应的权限传递到组件中。

1
<blog-post :post="{{ $post }}" :canUpdate="@json(auth()->user()->can('update', $post))"></blog-post>

我们在组件内部可以通过v-if来判断是否显示Edit按钮

1
<button v-if="canUpdate">Edit</button>

方法二

将对应的权限包含到post数据中返回给前端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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中的数据来处理权限问题

1
<button v-if="post.authorizations.update">Edit</button>

方法三

将相关的权限存储到数据库中。首先在users表中加入字段permissions,在这里保存权限信息,简单的demo如下:

1
2
$user->permissions = ["update-post", "destroy-post"];
$user->save();

针对复杂的情况可以用到多对多的数据库关系来储存(实际上就是我们经常用到的权限系统),然后在我们的blade模版顶部显示出权限信息。

1
2
3
4
5
<script>
window.App = {
permissions: @json(auth()->user()->permissions)
}
</script>

在Vue中我们通过window.App.permissions来进行权限处理。

方法四

与方法二很相似,只不过将getAuthorizationsAttribute替换成了API资源来进行处理,具体的内容可以查看文章底部的第二个链接。

讨论

就我个人而言,由于前后端分离,我一般使用的是第二种或者是第四种方法。不知道你们碰到这种情况会怎样处理呢?

参考