权限

前端跟后端关系

对于权限控制,首先需要明白一点:“权限的真正控制都必须是在服务端负责的”。

权限控制,本质是控制的用户对于 API 的操作权限,举一个例子,如果非管理员没有点击某个按钮执行某个操作的权限,那么如果仅仅是前端把这个按钮隐藏是无法做到真正的权限控制的。因为理论上用户可以直接发送一个接口请求服务端来完成这个操作。真正的权限验证应该放在服务端,这样哪怕用户绕过前端的限制请求了后端的接口也无法真正的完成操作。 所以对于前端来说,权限控制只是从 UI 层面告诉用户他有哪些权限和没有哪些权限。比如说隐藏某个按钮或者展示某些提示性的文字。

所以,这里说的权限,更多的是前端的 ui 控制。

请求接口

从前端发出的请求,cookie 会带到后端,后端可能会做一个权限判断,比如要是这个请求是没有的权限的,后端可能会返回 302,也可能会返回 200,在返回中带上没有权限的信息,比如:

{
  "success": false,
  "code": "NOT_AUTH"
}

对于 spa 应用,很多都是前端通过 ajax 请求后端 http 接口。要是后端返回 302 到一个 text/html 页面,那前端只能拿到这个页面的 response,另外要是 302 到了一个跨域的 url,前端根本拿不到返回值而是报错。因为前端请求 ajax 不能获得 302 这个状态,所以对于 ajax 没有权限,后端最好的做法是返回 200,带上错误信息,就像之前的代码。

权限控制

有不少的方式可表示用户权限,比如,后台返回一个用户的“权限码数组”:

{
  "auth": ["1", "2", "18", "20"]
}

表示用户有 1,2,18,20 的权限。这是一种比较简单方便的做法,后台通过权限中心获得用户的权限,再返回给前端。当前端获得了用户权限,那对于 ui 控制就简单了。比如:

// example 1
if (auth.includes("2") && auth.includes("3")) {
  return <Button>用户要有权限 2 and 3 才能看到按钮</Button>;
}
return null;

// example 2
if (auth.includes("1") || auth.includes("18")) {
  return <Button>用户要有权限 1 or 18 </Button>;
}
return null;

而对于路由,其实也是相同的方式,对于 react-router4,路由也是一个组件,所以方式跟之前相同,只是 Button 换成了 Route。