http域名在浏览器set-cookie失败,导致cookie中获取不到内容解决方案
由于开发一个表格系统时,前端使用的是Vue,后端使用的是 spring boot,在本地调试时用 localhost来访问,可以做到服务端和客户端使用cookie(HttpSession session) 通信,实现验证是否登录,但是在生产环境客户端(浏览器)在登录时无法set-cookie,导致cookie 信息没有保存在浏览器,其他接口无法做验证登录。
由于开发一个表格系统时,前端使用的是Vue,后端使用的是 spring boot,在本地调试时用 localhost来访问,可以做到服务端和客户端使用cookie(HttpSession session) 通信,实现验证是否登录,但是在生产环境客户端(浏览器)在登录时无法set-cookie,导致cookie 信息没有保存在浏览器,其他接口无法做验证登录。 在没有使用https 的情况下,解决重要步骤:
报错信息如图:
一、 前端部分
我使用的是vue-admin-template:
文件目录修改如下:
- 属性设置:withCredentials: true,
// 目录: vue-admin-template\src\utils\request.js
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
withCredentials: true, // send cookies when cross-domain requests
timeout: 50000 // request timeout
})
- 注释引入mock
// 目录: vue-admin-template\src\main.js
// if (process.env.NODE_ENV === 'production') {
// const { mockXHR } = require('../mock')
// mockXHR()
// }
3.前端使用Nginx代理的地址,与客户端访问地址、后端设置跨域地址保持一致
// 目录: vue-admin-template\.env.production
# just a flag
ENV = 'production'
# base api
VUE_APP_BASE_API = 'http://a.xxx.top/demo'
二、后端部分
- 跨域设置
package com.xx.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://a.xxx.top")
.allowCredentials(true)
.allowedMethods("*")
.maxAge(3600);
}
}
- application.yml 文件设置
server:
port: 8088
servlet:
context-path: /demo
session:
cookie:
domain: a.xxx.top
timeout: 24h
- 登录接口
@RequestMapping(path = "/login",method = RequestMethod.POST)
public Object login(@RequestBody LoginParams loginParams, HttpSession session) {
try {
if (StringUtils.isEmpty(loginParams.getMobile())) {
return new WebResponse(ErrorCode.NEED_MOBILE);
}
if (StringUtils.isEmpty(loginParams.getPassword())) {
return new WebResponse(ErrorCode.NEED_PASSWORD);
}
User user = userService.login(loginParams);
// 保存用户信息时,不保存密码
user.setPassword(null);
session.setAttribute(Constants.USER_INFO, user);
// System.out.println("登录 session id :" + session.getId());
System.out.println("登录 creator :" + session.getAttribute(Constants.USER_INFO));
return new WebResponse(ErrorCode.SUCCESS, user);
} catch (ServiceException serviceException) {
return new WebResponse(serviceException);
}
}
三、 Nginx部分
server {
listen 80;
server_name a.xxx.top;
charset utf-8;
# 允许跨域请求的域,* 代表所有
add_header 'Access-Control-Allow-Origin' *;
# 允许带上 cookie 请求
add_header 'Access-Control-Allow-Credentials' 'true';
# 允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
# 允许请求的 header
add_header 'Access-Control-Allow-Headers' *;
location / {
add_header Access-Control-Allow-Origin *;
root /www/wwwroot/demo/dist;
index index.html index.htm;
}
location /demo {
proxy_pass http://111.xx.xx.69:8088;
# 禁用 proxy_cookie_path 设置
add_header 'Access-Control-Allow-Origin' 'http://a.xxx.top';
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization, Accept-Language';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
# 设置 SameSite=None; Secure; HttpOnly
proxy_cookie_path / "/; secure; httponly; samesite=none";
}
}
如果出现:"尝试通过 Set-Cookie 标头设置 Cookie 的提作被禁上了,因为此标头具有“Secure"属性但不是通过安全连接接收的"
解决:去掉Nginx 配置中proxy_cookie_path 里的 “secure; ”
# 设置 SameSite=None; HttpOnly
proxy_cookie_path / "/; httponly; samesite=none";
本文参考案例:
https://blog.csdn.net/heidou_2016/article/details/127705402
https://blog.csdn.net/qq_35704369/article/details/126495891
其他改进方案
:
方案一:在生产环境中始终优先使用 https,以确保在客户端和服务器之间传输的数据的安全性。如果要设置带有 Secure 属性的 cookie,则必须使用 https。
方案二:后续开发过程可以考虑使用基于令牌(token)的身份验证方案,例如 JSON Web Tokens (JWT)。通过在每个请求中传递令牌,你可以绕过 SameSite Cookie 的限制。前端将令牌存储在本地,并在每个请求中将其发送到后端。后端验证令牌以进行身份验证。如果有问题欢迎留言讨论。
更多推荐
所有评论(0)