Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DjangoCMS: disable login via http, force https

Our DjangoCMS site is accessible via http and https.

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

Is there a way to force the usage of https as soon as the user wants to login?

Even the login-page (with username and password fields) should not be available via http.

Background: I don't want the password to go over the wire unencrypted.

Update: The site gets hosted on an apache web server.

like image 518
guettli Avatar asked Oct 16 '17 10:10

guettli


4 Answers

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:

  • Redirecting to SSL using nginx
  • Force redirect to SSL for all pages apart from one
like image 90
Thomas Schwärzl Avatar answered Nov 12 '22 19:11

Thomas Schwärzl


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

like image 39
markwalker_ Avatar answered Nov 12 '22 17:11

markwalker_


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")
like image 3
Zartch Avatar answered Nov 12 '22 19:11

Zartch


@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.

like image 3
John Moutafis Avatar answered Nov 12 '22 19:11

John Moutafis