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
- Django – Multiple apps on one webpage?
- Django REST: How to use Router in application level urls.py?
- Is there a way to check whether a related object is already fetched?
- How to install Django using brew?
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")
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.
- Differences between `class` and `def`
- Nullable TextField or empty string in Django model?
- Django – How to deal with the paths in settings.py on collaborative projects
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?
- Django ModelChoiceField has no plus button
- NameError:Admin not found in django
- Django – remove trailing zeroes for a Decimal in a template
0👍
You may use one or a combination of:
- htaccess file, take a look here
- webserver level, depend of server type: Apache, Nginx, IIS ?…
- django server level, take a look here, and host header validation or SSL/HTTPS