1. 认证
进入移动互联网时代,大家每天都在刷手机,常用的软件有微信、支付宝、头条等,下边拿微信来举例子说明认证相关的基本概念,在初次使用微信前需要注册成为微信用户,然后输入账号和密码即可登录微信,输入账号和密码登录微信的过程就是认证。
系统为什么要认证?
认证是为了保护系统的隐私数据与资源,用户的身份合法方可访问该系统的资源。
认证︰用户认证就是判断一个用户的身份是否合法的过程,用户去访问系统资源时系统要求验证用户的身份信息,身份合法方可继续访问,不合法则拒绝访问。
常见的用户身份认证方式有∶用户名密码登录,二维码登录,手机短信登录,指纹认证等方式。
2. 会话
用户认证通过后,为了避免用户的每次操作都进行认证可将用户的信息保证在会话中。
会话:就是系统为了保持当前用户的登录状态所提供的机制,常见的有基于session方式、基于token方式等。
2.1 基于session方式的认证
它的交互流程是:用户认证成功后,在服务端生成用户相关的数据保存在session(当前会话)中,发给客户端的sesssion_id存放到cookie中,这样用户客户端请求时带上session_id就可以验证服务器端是否存在session数据,以此完成用户的合法校验,当用户退出系统或session过期销毁时,客户端的session_id也就无效了。
2.2 基于token方式的认证:
它的交互流程是:用户认证成功后,服务端生成一个token发给客户端,客户端可以放到cookie或localStorage等存储中,每次请求时带上token,服务端收到token通过验证后即可确认用户身份。
2.3 基于session和token认证方式的不同:
- 存储规则不同。基于session的认证中,session_id必须存储在浏览器的cookie中;基于token的认证中,token没有硬性规定存储的位置。
- 两种方式会话的保持方式不同。
- 基于session的认证中,会话信息(session)必须存在服务端内存中实时存储从而保持会话,会占用服务器资源。
- 基于token的认证中,会话信息实际上是不需要存储的,通过token中的信息和JWT设置的token算法就可以保持会话,当服务端接收到token后就会根据JWT生成token的算法从而校验用户是否合法。
3. 授权
还拿微信来举例子,微信登录成功后用户即可使用微信的功能,比如,发红包、发朋友圈、添加好友等,没有绑定银行卡的用户是无法发送红包的,绑定银行卡的用户才可以发红包,发红包功能、发朋友圈功能都是微信的资源即功能资源,用户拥有发红包功能的权限才可以正常使用发送红包功能,拥有发朋友圈功能的权限才可以使用发朋友圈功能,这个根据用户的权限来控制用户使用资源的过程就是授权。
为什么要授权?
认证是为了保证用户身份的合法性,授权则是为了更细粒度的对隐私数据进行划分。授权是在认证通过后发生的,控制不同的用户能够访问不同的资源。
授权︰授权是用户认证通过根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则正常访问,没有权限则拒绝访同。
4. 授权的数据模型
4.1 授权的构成
如何进行授权即如何对用户访问资源进行控制,首先需要学习授权相关的数据模型。
授权可简单理解为:Who拥有对What/which进行How操作的权限。
- Who:即主体(Subject),主体一般是指用户,也可以是程序,需要访问系统中的资源。
- What:即资源(Resource),如系统菜单、页面、按钮、代码方法、系统商品信息、系统订单信息等。
- 系统功能资源:系统菜单、页面、按钮、代码方法都是功能资源,对于web系统每个功能资源通常对应一个URL。
- 系统数据资源:系统商品信息、系统订单信息都是数据资源,数据资源由资源类型和资源实例组成,比如商品信息为资源类型,商品编号为001的商品为资源实例。
- How:权限/许可(Permission),规定了用户对资源的操作许可。权限离开资源没有意义,如用户查询权限、用户添加权限、某个代码方法的调用权限、编号为001的用户的修改权限等,通过权限可知用户对哪些资源都有哪些操作许可。
- 功能权限:对功能资源操作的权限。
- 数据权限:对数据资源操作的权限。
4.2 主体、资源、权限关系
用户直接和权限挂钩,如果用户要想访问到某一个资源,必须给用户分配相应的权限。
4.3 完整数据模型
为了方便给主体分配资源的权限,在主体和资源之间引入了”角色”。角色相当于是一个权限的集合,例如管理员角色,包括了商品的增删改查。普通用户角色,只包括了商品的查询。
通过把权限分配给角色,当把角色分配给主体时,就相当于把权限分配给了主体。
完整数据模型的设计如下:
各个表的字段设计如下:
- 主体:(用户ID,账号,密码 …)
- 资源:(资源ID,资源名称,访问地址 …)
- 权限:(权限ID,权限标识,权限名称,资源ID …)
- 角色:(角色ID,角色名称 …)
- 主体角色关系:(主体ID,角色ID …)
- 角色权限关系:(角色ID,权限ID …)
4.4 实际数据模型
上述完整的数据模型是一个标准的数据模型的设计。而在实际开发中,通常将资源和权限合并成一张权限表。
实际数据模型的设计如下:
各个表的字段设计如下:
- 主体:(用户ID,账号,密码 …)
- 权限:(权限ID,权限标识,权限名称,资源名称,资源访问地址 …)
- 角色:(角色ID,角色名称 …)
- 主体角色关系:(主体ID,角色ID …)
- 角色权限关系:(角色ID,权限ID …)
5. RBAC
如何实现授权?业界通常基于RBAC实现授权。
5.1 基于角色的访问控制
RBAC基于角色的访问控制(Role-Based Access Control)是按角色进行授权,例如∶主体的角色为总经理可以查询所有员工工资信息。
访问控制流程如下:
根据上图,授权代码实现如下:
if (主体.hasRole("总经理角色ID")) {
查询所有员工信息;
}
复制代码
假如现在设置副总经理也可以查所有员工的工资,那么授权代码实现如下:
if (主体.hasRole("总经理角色ID") || 主体.hasRole("副总经理角色ID")) {
查询所有员工信息;
}
复制代码
根据上面示例,体现了基于角色的访问控制,在需求变更的情况下,代码实现也会变更,体现了健壮性,可扩展性差。
5.2 基于资源的访问控制
RBAC基于资源的访问控制(Resource-Based Access Control )是按权限进行授权,例如∶主体必须具有查询工资权限才可以查询所有员工工资信息。
访问控制流程如下:
根据上图,授权代码实现如下:
if (主体.hasPermission("查询工资权限标识")) {
查询所有员工信息;
}
复制代码
假如现在设置副总经理也可以查所有员工的工资,那么授权代码实现与上面不变。
根据上面示例,体现了基于资源的访问控制,在需求变更的情况下,代码实现不会变更,体现了健壮性,可扩展性强。
综上所述基于基于资源的访问控制比基于角色的的访问控制更加灵活,推荐使用基于资源的访问控制。