HTTP之访问控制「CORS」
序言
跨域资源共享「CORS」就是在不同的域名、协议、端口直接请求资源。本文主要讲述了什么是跨域,什么情况下会出现预检请求,我司的跨域安全访问
什么是跨域
同源策略
出于安全的原因,在没有被允许的情况下浏览器限制从不同源「origin」发起请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。
什么才能是同源
源:由协议+域名+端口组成,也就是说,这个三个要统一才同源
例:
- http://www.baidu.com && https://www.baidu.com 不同源 协议不同
- http://**api.baidu.com** && http://**www.baidu.com** 不同源 域名不同
- http://**www.baidu.com:8081** && http://**www.baidu.com:8080** 不同源 端口不同
- www.baidu.com/index.html && www.baidu.com/404.html 同源
什么情况下会出现预检请求
预检请求
跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。在某些会对服务器数据产生作用「需要修改数据库」的请求「主要是GET以外的请求」,浏览器会先发送通过OPTIONS方法发送预检请求,从服务器那边得到返回是否允许跨域。服务器也可以携带是否需要身份凭证通知浏览器。
也就是说:在你发送请求的时候,浏览器会自己先发送一个预检请求。后台只需要识别请求的方法「OPTIONS」,然后返回一些信息。 如下图:
这里有两个login/请求,第一个是浏览器主动发出的。它的Request Method方法为 OPTIONS,然后服务器的返回信息:
- access-control-allow-headers:允许你携带头的参数
- access-control-allow-methods:允许你发送请求的方法
- access-control-allow-origin:允许你发送请求的地址
这部分信息通知了你修改自己的请求参数来符合服务器的要求, 服务器如何除了浏览器发送的预检请求,可以参照这个MDN Server-Side_Access_Control (CORS)。
简单请求
在以下情况下发送的请求不会触发预检请求
- 使用以下方法之一:「GET HEAD POST」
- 头部字段在这个集合之内:「Accept, Accept-Language, Content-Language, Content-Type (需要注意额外的限制), DPR, Downlink, Save-Data, Viewport-Width, Width」
- Content-Type以下三种之一:「text/plain,multipart/form-data,application/x-www-form-urlencoded」
- …
例子:我在发送登录的时候,头部字段自定义了Authorization,这时候就触发预检请求
我司的访问控制方式
JSON Web Token「JWT」
公司主要采用的就是JWT的跨域认证解决方案。JWT的意思就是:用户发送登录信息「用户名,密码」给服务器,服务器认证后生成一个JSON对象,给用户储存,之后用户请求数据都需要带上JWT来发送请求。
步骤
- 登录 发送用户名密码给服务器验证返回JWT
- 前端通过LocalStorage储存JWT
- 之后的请求带上JWT
- 验证过期或者失败直接返回401退到登录页面
不足之处
- JWT一旦签发了,在到期之前始终有效,这样别人可以使用你的JWT获取数据
- JWT过期或失效的时候,用户仍然需要通过失效的JWT请求才能知道JWT已经失效
扩展阅读
如果前端没有跟后端建立统一API设计规范,可以使用这个 RESTful api
参考
MDN HTTP访问控制 阮一峰 JWT入门教程
转载于//juejin.im/post/5ccd2222518825408612c23a
还没有评论,来说两句吧...