此文基于官方文档教程,是对其代码细节的解释文档。
可以先尝试阅读官方文档教程,它看起来也不算太难理解。 地址: 点此查看
当然也可以继续往下看。 (●'◡'●)
@delonn/auth是对认证过程的进一步处理,它只关注并解决以下三个问题:
- 如何获取认证信息
- 如何读写认证信息并监听信息变化
- 如何使用认证信息(分别在JWT/SWT)
@deloon/auth 并没有HTML和CSS代码,它是完全TS实现,这意味着它只关注对用户认证这一块儿的程序逻辑实现,并不关注界面,同时也可以用在其他基于TS的前端项目。
import { ITokenService, DA_SERVICE_TOKEN } from '@delon/auth';
在@delonn/auth 中,有一个最关键的服务,它将与用户直接打交道——ITokenService。
login.component.ts 文件
image如上图所示,使用 InjectionToken模式获取ITokenService的依赖注入。
在当用户登录成功并且获取到后台API返回的令牌后,通过调用ITokenService的set方法写入本地存储(115行)。set方法需要传入一个对象,该对象必须满足接口 ITokenModel,此接口只有一个string类型的token属性。 业务模型理应如右图所示: image
加载程序和用户信息
image.png在项目的启动入口 startup.service.ts文件中,必须加载用户数据和程序数据。上图代码运行在理想环境,(并未检查token是否有效)。
拦截器
SimpleInterceptor是ng-alain内置的一个拦截器,它会在httpClient对象的post、get、delete、putch等方法中自动填入我们刚刚存储到本地的token信息。所以,当startup.service.ts内部的http请求执行后,拦截器发现没有token时,将不会发出实际请求,而是跳转到登录页。
image设置此拦截器的提供商。同时你需要知道的是此拦截器框架由angular设计,非ng-alain。
拦截器的源代码
该文件位于【node_modules_@delon_auth@0.6.5@@delon\auth\token\simple\simple.interceptor.js】
定位到SimpleInterceptor.prototype.intercept方法的实现。
image方法的第一部分代码实现了检查忽略列表,忽略ignores中存储的URL地址,这意味着并不会插入token。所以这个列表中必须有登录API,好让登录页能正常发起请求而不是由拦截器中止请求。
方法的第二部分设置了例外情况,如果你在@delon/auth模块的全局设定对象【AuthOptions】的属性allow-anonmous-key设置为true,或请求参数params中包含allow-anonymous-key,也将忽略token,直接发起请求。
image方法的第三部分获取ITokenService对象并将token取出,根据全局设定对象的属性【token_send_place】中指示的位置将token按规则插入,紧接着发起请求。
方法的第四部分是上图的else代码段。当model或model.token没值时,路由将跳转到最初设定好的登录地址。
在模块被注入时设置用户认证的全局设定
image用户认证模块位于【delon.module.ts】文件,默认仅有两个属性生效。
ignores:博主设置了'/Auth/TokenByUserInfo'为不添加token的URL。所有不在ignores数组中强调的地址都将检查token,如果没有将中止请求。
login_url:设置当缺失token时拦截器自动跳转的登录路由。
store_key:设置存储在本地token值的键名,默认为'token'。可以按需求更改,但在调用ITokenService.set方法时传递的对象依然得满足ITokenModel接口。
token_send_key:设置token在http请求中的参数名,区别于store_key。
token_send_place:指示token在http请求中的存储位置。('header' | 'body' | 'url')
allow_anonymous_key:允许匿名登录,请参阅本文上方分析拦截器源代码的第二部分。
到这里用户认证就差不多的了:从登录成功后存储token,到发起请求时携带token。 我们在使用@delon/auth包时只需要关注这两点即可。以下是一些特别需求。
如何将token存储到浏览器的不同位置
ITokenService是设置token的服务,查阅它的实现不难发现有一个属性叫IStore,字面意思不用想肯定是存储,再深究才恍然大悟原来不是ITokenService读写本地存储的token,而是ITokenService借用IStore管理token的读写,同时这样的分离设计也为我们实现不同的存储器省了不少事儿,为卡色大佬点赞!
默认情况下token存储在localStorage中,接下来要实现存储在sessionStorage中,这意味着token将在浏览器关闭时销毁。
image新建一个token存储器服务并实现IStore接口,无需关注token存储在本地的键名,因为ITokenService会把在用户认证的全局对象中设定的属性名传入(store_key)。
image然后在依赖提供商内使用InjectToken模式注册存储器服务。
最后运行项目并登录用户后,在dev tools内打印浏览器的sessionStorage对象后即会发现token已生效。
请注意,上面的方法可以设置@delon/auth包的认证信息在浏览器不同的位置。但你需要知道的是最新版本已内置sessionStorageStore和memoryStore:
image根据项目的实际业务需求在此处设置的两个依赖注入供应商中保留一个即可。
权限控制
image@delon/acl 包是ng-alain内置的权限控制模块,在启动服务内标记为非全量模式,并设置用户具备的权限点/角色。
image如左图所示,具备的权限点是一个字符串数组,这是用户具备的所有权限点。通过对相应标签设置acl指令来控制显示还是隐藏。
<button acl [acl-ability]="'Main.Main'"></button>
具体可点击此处查阅设置方法。
网友评论