📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍
文章目录
- 写在前面的话
- 接口鉴权实战
- 鉴权设计
- 后端实现
- 前端改造
- 其他考虑
- 总结陈词
写在前面的话
博主所在公司,后端技术栈为SpringCloudAlibaba
,前端为Vue/Nuxt
,现新开本系列博文,以此技术栈为例,介绍企业在前后端分离和微服务开发模式下的相关实战过程分享。
接口鉴权是所有框架中,必须考虑的一个环节,本系列博文也以此开篇。
接口鉴权实战
鉴权设计
博主所在公司整体采用前后端分离+微服务架构,所有业务系统,拥有一个统一工作门户,用户管理整体的登录入口,通过单点登录SSO机制,实现各业务系统的免登录,“一次登录、到处运行”,当然本篇文章主要不是介绍SSO的,先聊一下“接口鉴权”的那些事情。
【设计流程如下】
用户登录门户后,门户认证模块会将用户 Token 存储到 Redis,后续接口调用将验证请求头是否携带Token,并对Token 做二次验证,如果验证通过会将用户信息放入请求头中,可以通过用户信息工具类获取相应用户信息。反之,验证不通过则予以报错。
【简单流程图】
后端实现
【实现鉴权】
后端要实现接口鉴权,通常可以采用过滤器和拦截器,如果有不清楚的,可以再看看之前的博文《知识点扫盲 · 过滤器 Filter》和《知识点扫盲 · 拦截器 Interceptor》。
具体添加鉴权的环节通常也有两种:1、网关Gateway直接校验;2、框架核心公用包添加校验;
两种方式各有优缺点,博主所在公司采用第二种方案。
实现思路大体:
- 核心包内自定义实现拦截器,例如TokenInterceptor;
- 该拦截的preHandle方法内,获取请求头的token信息,判断是否需要校验以及是否为空;
- 继续从Redis中获取该Token的用户信息,存在则设置到请求头内,为空则给予异常;
【登录改造】
门户登录成功后,应该会生成一个唯一的Token代,并且存储到Redis中,Key是Token,Value是用户信息,同时返回相关信息给前端。
前端改造
登录成功后,前端本地缓存会存储 lw_token 和 lw_userInfo 两个信息。
lw_token 存储 token 信息,后端可以根据它从 Redis 中拿到用户信息;
lw_userInfo 存储用户请求头信息,部分信息如下。
存本地缓存的目的是,方便所有业务系统可以快速查阅。
//以下数据仅为范例
{
"districtCode": "1",
"staffNo": "4129",
"districtName": "",
"orgCode": "46667016-1",
"name": "门户",
"language": "zh",
"operator": "4129",
"userCode": "9113"
}
【前端验证流程】
所有前端请求后端接口处(Axios封装模块),都会先校验这两个参数是否存在,不存在前端则直接报错。
之后会在请求头携带 lw_token,网关层会针对请求的 lw_token 做二次校验(也可以是LwToken),若不存在则抛出异常。
网关解析 Lw_token 后,可以拿到用户信息放入请求头,后续所有服务都可以拿到相应请求头(包括Feign调用的后续接口)。
其他考虑
【如何关闭鉴权】
下方是一些鉴权配置项,仅供参考。
lw:
auth:
# 是否开启Token验证 (默认开启)
enabled: false
# 是否验证请求时间 (默认关闭)
validate-call-time: false
# callTime有效期 (s=秒,m=分钟,h=小时,d=天) (默认2分钟内的请求有效)
call-time-expiration: 3m
# 白名单列表,跳过验证(支持Spring通配符)
permit-urls:
- /demo/test1/**
- /demo/*/test2
- /demo/test3
【有效期设计】
由于Token存在在Redis中,而且属于高频生成量,建议要添加上有效期。
否则久而久之会影响Redis性能。
【Feign调用鉴权】
不止前端访问后端,后端之间的Feign调用也可以考虑一下是否鉴权。
这里篇幅限制,不展开赘述,后续可以专栏介绍。
总结陈词
此篇文章介绍了接口鉴权
在企业实战中如何实现,仅供学习参考。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。