[Fixed]-DjangoCMS: disable login via http, force https

16👍

As I already mentioned it in the comments I strongly suggest you to NOT only serve the login page via https.

Doing so just hides the fact that for example session information and authentication data is still transfered on the other requests unencrypted via http. Your site will not be secure at all.

You’re just pseudo-securing stuff so it’s fancy to somebodys eye. It’s just like using the password 12345.

So please serve your website over https to the user. A small guide, for nginx or apache2, on how to redirect your traffic from http to https can be found here:

4👍

As you’ve accepted in the comments, pushing all traffic to HTTPS is the best solution these days. If you only authenticate via SSL, you’ll need to consider encryption/security in everything you write moving forward rather than it just being the default.

So in your server config, force all traffic to port 443. Assuming you’re using apache you’d do this;

 <VirtualHost *:80>
     ServerName www.example.com
     Redirect / https://www.example.com/
 </VirtualHost>

 <VirtualHost *:443>
     ServerName www.example.com
     # ... SSL configuration goes here
 </VirtualHost>

Then in your Django settings turn on secure cookies;

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

As a side note, Django has a setting to redirect HTTP traffic to HTTPS which is SECURE_SSL_REDIRECT, but if you’re doing this at the apache/nginx level you don’t need to worry. For some further reading on SSL/HTTPS have a look here; https://docs.djangoproject.com/en/1.11/topics/security/#ssl-https

3👍

Django request has a is_secure()

You can check it in the view and redirect if not is secure:

if not request.is_secure():
    return redirect("https://www.yourdomain.com/login")
👤Zartch

3👍

@user1 has the logic right and you should serve your site through https in order to have it safe.
But in order to answer your exact question:

As shown here: How to know using Django if server is secure (uses https) and as @Zartch mentions in his answer, you should use the is_secure() HTTPRequest method to check if your request is coming through https.

  • In order to use is_secure() you need to check an incoming request
    to your views:

    def my_login_view(request):
        if request.is_secure():
            Do loggin
        else:
            Don't login
    
  • Now you can protect your other views with the login_required decorator:

    @login_required(login_url='/your/login/url')
    def protected_view(request):
        ...
    

Personal suggestion: I use Django Rest Framework extensively and I would suggest it, in your case, because it has an isAuthenticatedOrReadOnly permission class which you will like:

class MyLoginView(ObtainAuthToken):
    """
    Login view for token-based authentication
    """
    def post(self, request, *args, **kwargs):
        if request.is_secure():
            super().post(request, *args, **kwargs)
        else:
            Probably some redirect goes here...

Then in any other view or class-based view:

class MyOtherView(generics.GenericAPIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    ...

The above will ensure that your users can login only through https and if they are not logged in they will only see a read-only view.

Give it a try if you like.

2👍

You didn’t accept an answer yet, so I thought, that the answers might not match your question well enough.

Anonymous usage via http is ok. But I want to disable logins via http.

As I understand, you have the following use case:

Some person visits your website as anonymous user, the used protocol is http.
This person opens the login form and logs in, the form is sent through https.
The logged in user continues browsing your website through https.

If the login form is routed to the secure version your user will continue browsing your website in https mode (as long as all other links are agnostic to the used protocol).

<form action="https://your.domain/path/to/login/" method="post">

If the application you’re using to authenticate users is sanely written, you can configure your settings.LOGIN_URL, else you’ll probably need to do it in the template form.

I recommend allowing session cookies to be sent only through https, using settings.SESSION_COOKIE_SECURE.
With this setting, the user will still be able to make http requests, but the session cookie will not be sent (and the user will be treated as an anonymous user).

Please, make sure that your login view accepts only secure post requests (or else the user may send the password through non https protocol).
This can be achieved either in the Django code (like John Moutafis suggests with his MyLoginView) or at production server level by rejecting non https post requests for the login URL.

Could you provide access to the repository with the code?

0👍

You may use one or a combination of:

Leave a comment