登录逻辑采用session存储,并采用分布式redis缓存。
登录代码
request.getSession().setAttribute(USER_LOGIN_STATE, safetyUser);
验证代码
if (loginUser == null) {
throw new BusinessException(ErrorCode.NO_LOGIN, "未登录");
}
session配置
spring:
session:
timeout: 86400
store-type: redis
上线时出现的问题
就是出现了跨域请求,浏览器默认在页面跳转时无法携带cookie
解决方案
server:
port: 8081
servlet:
context-path: /api
session:
cookie:
domain: 域名
same-site: lax
secure: false
- 使用一级域名,因为二级域名也可以被解析为一级域名
- 此方案必须在firefox下使用,chrome目前版本仍然被禁止
方案二
server:
port: 8081
servlet:
context-path: /api
session:
cookie:
domain: 域名
same-site: none
secure: true
- same-site设置为none,secure必须为true。此时需要SSL证书,使用https协议,方可成功
原理探究:
chrome开始支持新属性SameSite,解决接口Cookie被滥用以及CSRF的问题。
SameSite属性简介
ameSite是Cookie的一个属性,其和path,domain一样,是一个普通的Cookie属性。其作用是限制该Cookie的在请求的时候是否被传递到Cookie所属服务的场景。
它一共有三个值,其基本含义分别如下:
Strict
Strict最为严格,完全禁止第三方 Cookie。即在跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
设置方式为:Set-Cookie: CookieName=CookieValue; SameSite=Strict;
Lax
Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外( top-level navigations)。
所有浏览器的Cookie默认SameSite属性都为Lax,即SameSite设置为空(未设置),则表示为Lax。
设置方式为:Set-Cookie: CookieName=CookieValue; SameSite=Lax;
设置了Strict或Lax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。
None
如果设置为None(前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效)。此时就表示Cookie不受约束在任何跨域场景下,只要设置了withCredentials=true都会发送到三方服务端。
设置方式为:Set-Cookie: CookieName=CookieValue; SameSite=None; Secure;
参考文章:
https://juejin.cn/post/6999262693715050533