问题描述
使用如下sa-token配置,前端通过IP+端口号的方式访问后端服务,会存在options预检请求鉴权失败的问题。
问题分析
http-options请求
HTTP
OPTIONS
方法请求给定的 URL 或服务器的允许通信选项。客户端可以用这个方法指定一个 URL,或者用星号(*
)来指代整个服务器
通过options请求,我们可以检测服务器所支持的请求方法。
预检请求
CORS 预检请求用于检查服务器是否支持 CORS 协议,并且是否允许使用特定的方法和标头。
当有必要的时候,浏览器会自动发出预检请求;所以在正常情况下,前端开发者不需要自己去发这样的请求。预检请求会在请求被标记为“需要预检”时进行,而对于简单请求则不会进行。
CORS中的预检请求
与简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
当客户端尝试对一个与当前源不同的服务器发起跨域 HTTP 请求时,如果该请求包含复杂的 HTTP 方法(比如 PUT、DELETE)或使用了一些特殊的请求头(如 Authorization),浏览器会自动先发出 OPTIONS 请求,检查服务器是否允许该请求。这个过程称为预检请求 (Preflight Request)。通过预检,浏览器可以在发送实际的 HTTP 请求之前,确保服务器接受该请求,避免不必要的数据传输。
解决方案
当出现预检请求的时候,会发现sa-token鉴权无法通过,即使登录成功了,也会由于options请求鉴权失败,而导致接口无法访问。以下为两种解决方案,
方式1:修改客户端请求方式
调整请求方法、去除自定义header、修改Content-Type,基本可以避免该请求发出OPTIONS预检请求。
方式2:服务端控制,放行options请求
代码如下,