最近在工作上需要将一个旧项目进行前后端分离, 前端采用react。
前期进展顺利,本地测试是有个问题,login存储不上,但在将host改为localhost后就可以了。
当上线服务端是出现了问题,登录后sessionid不进行存储。
INSTALLED_APPS = [
...
'corsheaders'
]
CORS_ALLOWED_ORIGINS = [
'http://域名.com',
'https://域名.com',
'http://react服务器ip:3000',
'https://react服务器ip:3000'
]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware'
]
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ("CustomAuthentication", )
}
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
CACHES = {
'default': {
'BACKEND': "django_redis.cache.RedisCache",
"LOCATION": "redis://localhost:6379/3",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
}
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
export default class App extends Component {
testRequest = () => {
axios({
method: 'GET',
url: 'http://指向后端/login/',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
withCredentials: true
}).then(res => {
alert(res.data)
})
}
handleSubmit = (event) => {
event.preventDefault()
this.testRequest()
axios.defaults.withCredentials = true;
const csrftoken = GetCookie('csrftoken')
console.log(csrftoken)
const data = new FormData(event.currentTarget);
axios({
method: 'POST',
url: 'http://指向后端/login/',
dataType: 'json',
data: {
'username': data.get('username'),
'password': data.get('password'),
},
headers: {
"X-CSRFtoken": csrftoken,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
timeout: 100000000000,
withCredentials: true
}).then(res => {
console.log(res)
}).catch(res => {
console.log(res)
})
}
render() {
return (
<Box component="form" onSubmit={this.handleSubmit} noValidate sx={{mt: 1}}>
<TextField
margin="normal"
required
fullWidth
id="username"
label="UserName"
name="username"
autoComplete="username"
autoFocus
/>
<TextField
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary"/>}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
sx={{mt: 3, mb: 2}}
>
Sign In
</Button>
<Grid container>
<Grid item xs>
<Link href="http://指向后端/logout/" variant="body2">
logout
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</Box>)
}
}
查了下以为是django设置问题,搞了半天,发现毫无意义。
开了个小demo项目,测试发现是代理问题,本人使用apache代理,如果直接IP请求,sessionid是可以存储的,而使用ip代理后,sessionid不进行存储。这时候意识到是apache的问题。(这里已经过了一天了 笑)
打开浏览器的开发者工具,查看登录post请求,发现set cookies后面有个黄色感叹号。(这里不放图了,搞了两天累了)
this attempt to set a cookie via a set-cookie header was blocked because it had the ‘secure’ attribute but was not received over a secure connection
this set-cookie header didn’t specify a “samesite” attribute and was defaulted to “samesite=LAX” and was blocked because it came from a cross-site response which w…
这时候判断是这个samesite问题,查谷歌能不能设置,之后就是漫长的瞎折腾。
到刚刚才突发奇想,既然是同源问题,那将前端与后端都挂在一个域名下试试呢
前端设置 login.域名.com
后端设置server.域名.com
成功!
cookie存储在server.域名.com下 并且成功完成了登录后下一页的数据展示。
到此花了两天时间搞这么个破事。
记录完毕。
Original: https://blog.csdn.net/Ch_Chenjs/article/details/124301996
Author: Ch_Chenjs
Title: django-react 服务端挂载apache代理 域名 sessionid不存储问题
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/735825/
转载文章受原作者版权保护。转载请注明原作者出处!