美文网首页
laravel+react实现前后端分离权限系统的设计

laravel+react实现前后端分离权限系统的设计

作者: __missing | 来源:发表于2019-03-04 18:49 被阅读0次

前言

在前后端分离的情况下,做权限系统首先要确定粒度问题,在本文中谈论的前端粒度为菜单级别(暂时不考虑按钮级别),后端的粒度就是接口。

设计思路

其实前后端分离的权限系统的主要控制还是在后端,前端只是一个简单的拦截。大体思路就是在用户登录成功之后,后端接口将用户下的所有菜单返回,前端存起来展示给用户,后端在接受到请求时,判断此请求者对于此接口是否有权限如果没有就返回403,否则继续执行。

表结构

user(id, email, name, password, token);
role(id, name,comment);
user_role(id, user_id, role_id);
menu(id, parent_id, name, route, comment);
permission(id, name, route)
role_menu(id, role_id, menu_id)
role_permission(id, role_id, permission_id)
menu_permission(id, menu_id, permission_id)

实现

后端实现

// 这是一个中间件,对于任何请求判断是否有权限
class CheckAccess {
    public function handle(Request $request, Closure $next)
    {
        $user = get_loggined_user(); //获取请求接口的用户

        $userRepo = new UserRepository($user);
        if ($userRepo->isSuperAdmin()) { //判断用户是否为超级管理员
            return $next($request); //超级管理员拥有所有接口的权限
        }

        try {
            $permission = $this->getPermission($request); //这个方法根据请求路由去表permission中查询,是否将接口加入权限表如果没有添加,表示没有权限,具体细节看getPermission方法。
        } catch (PermissionNotFoundException $e) {
            return response(['code'=>403001,'message'=>'没有权限'], 403);
        }

        if ($userRepo->hasPermission($permission)) { //判断这个用户是否拥有权限,这个判断其实就是先找出用户的角色,去role_permission表中查找是否可以找到,如果找到就表示有权限。
            return $next($request);
        }
        else {
            return response(['code'=>403001,'message'=>'没有权限'], 403);
        }

    }

    protected function getPermission($request)
    {
        $route = '/'.$request->path(); 
        $uri = '/'.$request->route()->uri(); 
        $dbroute = substr($route,strlen(env('PREFIX')));
        $dburi = substr($uri,strlen(env('PREFIX')));

        $permissionRepo = new PermissionRepository(new Permission());
        $perg = '/\{[\w]*\?{0,1}\}/';

        if ($route == $uri) {
            $permission = $permissionRepo->findByRoute($dbroute);
        }  else {
            try {
                $permission = $permissionRepo->findByRoute($dbroute);
            } catch (PermissionNotFoundException $e) {
                $permission = $permissionRepo->findByRoute(preg_replace($perg, '*', $dburi));  //这个主要是解决  ‘/users/{id}/index’ 这一类的路由,在数据库中应该存‘/users/*/index’
            }
        }
        return $permission;
    }
}


class User{
    public function menus(int $userId)
    {
        try{
            $user = $this->userRepo->findById($userId); //获取请求的用户
        } catch (UserNotFoundException $e) {
            return response($this->getErrorMessage(ErrorCodeClass::OBJ_NOT_FOUND, $this->userRepo.ErrorCodeClass::OBJ_NOT_FOUND_MSG), HttpCodeClass::NOT_FOUND);
        }

        $this->userRepo = new UserRepository($user);

        $menus = $this->userRepo->getMenus(); //查找用户下的所有菜单,供前端展示

        $menuTree = $this->menuRepo->changeTree($menus->where(FieldConstants::IS_SHOW, 1)->all());

        $resource = new MenuResource($menuTree);

        return response($resource->transformMenu(), HttpCodeClass::OK);

    }
}

前端实现

前端通过请求后端的menus将获取到菜单展示在菜单栏,到目前为止虽然权限控制的功能实现了,但是大家有没有想过这种将前端菜单和后端权限独立开的设计,如果要开发一个新功能,就需要将将菜单和接口权限都添加给角色,这里我们有使用了menu_permission这个表,将权限和菜单关联起来,其实他两的关联关系只是为了前端添加权限的时候方便

相关文章

网友评论

      本文标题:laravel+react实现前后端分离权限系统的设计

      本文链接:https://www.haomeiwen.com/subject/rcaiuqtx.html