关于前后分离项目中图片鉴权的一种解决方案
钢翼
编程
一、背景
上传的图片和文件一般分为公共和私有两种存储。
- 公共存储的资源允许游客访问,一般通过静态资源映射下即可。
- 私有存储的资源需要鉴权,有权限的才允许访问,需要通过控制器控制访问权限。
如果不是前后分离的或者前后分离均在一个根域名下,直接采用cookies存储即可解决。
但如果前后分离不在同一根域名下,就有点麻烦了。当采用前后分离,api接口的token一般会放到header中传递。但是图片这些资源并不会携带我们自定义的header的。所以这里不能通过header鉴权。
如果通过url传递token的话,需要对每个图片地址都进行处理,显然也不是一个好的方案。
二、想要的结果
- 1.能直接在img上显示鉴权图片
- 2.能直接通过地址栏打开鉴权文件
- 3.原有api接口不需要改动
三、解决方案
后端:
- 1.后端增加一个接口A(get请求),入参只有一个token,由前端传给后端。后端直接关联sessionId即可。(注:接口A不通过ajax请求)
- 2.图片和文件控制器(get请求)先根据sessionId获取接口A存储的token,然后对token进行认证。
- 3.增加过滤器,当response中存在Set-Cookie的header时,需要在后面添加SameSite=None,chrome80以上版本的跨域不加此参数,会无法设置cookie。(后端必须是https协议)
添加SameSite,可参考https://blog.csdn.net/y1378503395/article/details/108236630
由于添加后会重复,可以通过反射操作MimeHeaders进行删除,参考https://blog.csdn.net/huangdengji/article/details/108006618
前端:
- 1.登录后的首页加载一个长宽为1的图片,src为接口A的地址,记得将token拼接在url参数中。
- 2.登出操作,请同样用img加载接口A,token传空即可。 注意:请不要尝试在登出api内清除sessionId和token的关联关系,因为ajax请求都是不传递cookie,每次都是新建session。