0

please help me!!!

My project backend is django and frontend uses react.

Local testing with localhost works fine.

When I go online on the server and adjust the apache domain name, the sessionid cannot be automatically stored. I have tried many methods, but they are not available.

But I found that if I don't use the apache proxy, it works fine if I use the ip directly, and the sessionid can also be stored. What is the reason for this? The code I put below.

By looking at the application page in chrome's developer tools, The cookies are used to determine whether the sessionid is successfully set. In this process, the domain name request has not been stored, and the ip request is very normal.

doamin name request doamin name result

ip request ip result

Django Settings

INSTALLED_APPS = [
    'whitenoise.runserver_nostatic',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'django_crontab',
    'command_app',
    'djcelery',
    'corsheaders'
]

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware'
]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
# CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOWED_ORIGINS = [
    'http://react server ip:3000',
    'https://react server ip:3000',
    'http://localhost:3000',
    'http://server ip:3000',
    'https://server ip:3000',
    'http://www.my domain name.com',
    'https://www.my domain name.com',
    'http://my domain name.com:3000',
    'https://my domain name.com:3000',
    'http://my domain name.com',
    'https://my domain name.com',
]
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",  # TODO 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"

Django View

class LoginAPI(generics.GenericAPIView):
    authentication_classes = (SessionAuthentication, )
    serializer_class = LoginSerializer

    def post(self, request):
        print(request.session.session_key)
        print(f"LoginAPI IsLogin: {request.user.is_authenticated}")
        if request.user.is_authenticated:
            return HttpResponse(dumps({'message': 'Login!'}), content_type='application/json', status=status.HTTP_200_OK)
        serializer = self.get_serializer(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
        except ValidationError:
            return HttpResponse(status=status.HTTP_401_UNAUTHORIZED)
        user = serializer.validated_data
        login(request, user)
        return HttpResponse(dumps({'message': 'Logout Success!'}),
                            content_type='application/json', status=status.HTTP_200_OK)

    def get(self, request):
        print(request.session.session_key)
        if request.user.is_authenticated:
            return HttpResponse(dumps({'message': 'Login!'}), content_type='application/json', status=status.HTTP_200_OK)
        else:
            return HttpResponse(dumps({'message': 'Not Login!'}), content_type='application/json', status=status.HTTP_401_UNAUTHORIZED)


def my_logout(request):
    print(request.session.session_key)
    print(f"my_logout Is Login: {request.user.is_authenticated}")
    logout(request)
    return HttpResponse(dumps({'message': 'Logout Success!'}), content_type='application/json', status=status.HTTP_200_OK)

urls.py

urls.py
urlpatterns = [
    path('login/', LoginAPI.as_view()),   # new web
    path('logout/', my_logout),   # new web
]

React Code

export default class App extends Component {
    testRequest = () => {
        axios({
            method: 'GET',
            url: 'http://server:8049/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://server:8049/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 (
            <div><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://http://my domain name:8049/logout/"variant="body2">
                                        logout
                                    </Link>
                                </Grid>
                                <Grid item>
                                    <Link href="#" variant="body2">
                                        {"Don't have an account? Sign Up"}
                                    </Link>
                                </Grid>
                            </Grid>
                        </Box>
                    </Box>
            </div>)
    }
}

Apache Code

<VirtualHost *:80>
   ServerAdmin webmaster@user.com
    DocumentRoot /home/ec2-user/project_path
    ServerName www.my domain name.com
    ServerAlias my domain name.com
     ProxyPass / http://localhost:8048/
     ProxyPassReverse / http://localhost:8048/
</VirtualHost>
jason chen
  • 21
  • 3
  • 1
    `the sessionid cannot be automatically stored` How do you know this is the problem? Are you getting an error? If so, please post it. – John Gordon Apr 20 '22 at 02:44
  • 1
    Refer to [Why does Django not generate CSRF or Session Cookies behind a Varnish Proxy?](https://stackoverflow.com/questions/6065503/why-does-django-not-generate-csrf-or-session-cookies-behind-a-varnish-proxy?rq=1) – Liki Crus Apr 20 '22 at 03:22
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Apr 20 '22 at 03:22
  • Questions updated and pictures added – jason chen Apr 20 '22 at 06:30
  • There would be variables to use the django cache session like session expired time. Try to check how to use the django cache session. – Siva Sankar Apr 20 '22 at 09:49

2 Answers2

1

Change ALLOWED_HOSTS to ALLOWED_HOSTS = ['*'].

Kovy Jacob
  • 489
  • 2
  • 16
0

On a whim, I assigned subdomains to the frontend and backend. Is this guaranteed to be homologous. I sent a request in this case, and found that the backend domain name successfully stored the sessionid, and successfully determined the login status in the next request. Although it is very strange, it does fulfill my needs.

jason chen
  • 21
  • 3
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 20 '22 at 10:01