django-react 服务端挂载apache代理 域名 sessionid不存储问题

最近在工作上需要将一个旧项目进行前后端分离, 前端采用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/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球