Django Login/Logout System Part-I

earthcomfy

Hana Belay

Posted on August 27, 2021

Django Login/Logout System Part-I

Hey guys, how have you been? In today's part we are going to create the login system with a remember me cookie option


Here again, we don't have to reinvent the wheel thanks for the built in django's authentication system. We can build our authentication system by extending from that and customize it to meet our needs.

Django gives this authentication support in its module django.contrib.auth whose configuration is already included in settings.py when we created our project in the very beginning. This built in auth app gives us login, and logout views together with other password management views that we will go over in later parts of the series.

  • Great. Now let's see how we can put all this together.

Let's start from the login form. Django has a built in AuthenticationForm which is a base class for authenticating users based on username and password.

  • We will create our login from by extending from it to add a remember me checkbox, and also bootstrapify the username and password fields using widgets as we saw in the previous posts.

  • A remember me option is a nice to have feature since users don't want to fill in credentials every time they visit a site.

forms.py

# Add this to previous list of imports
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm 


class LoginForm(AuthenticationForm):
    username = forms.CharField(max_length=100,
                               required=True,
                               widget=forms.TextInput(attrs={'placeholder': 'Username',
                                                             'class': 'form-control',
                                                             }))
    password = forms.CharField(max_length=50,
                               required=True,
                               widget=forms.PasswordInput(attrs={'placeholder': 'Password',
                                                                 'class': 'form-control',
                                                                 'data-toggle': 'password',
                                                                 'id': 'password',
                                                                 'name': 'password',
                                                                 }))
    remember_me = forms.BooleanField(required=False)

    class Meta:
        model = User
        fields = ['username', 'password', 'remember_me']
Enter fullscreen mode Exit fullscreen mode
  • We have seen how forms are created in the last part when we created the sign up form so we won't go much into detail here.

Next, let's set up the view to use the login form we created. Django also has a built in LoginView. We can override some of the class's attributes and methods to meet our needs.

views.py

from django.contrib.auth.views import LoginView
from .forms import RegisterForm, LoginForm

# Class based view that extends from the built in login view to add a remember me functionality
class CustomLoginView(LoginView):
    form_class = LoginForm

    def form_valid(self, form):
        remember_me = form.cleaned_data.get('remember_me')

        if not remember_me:
            # set session expiry to 0 seconds. So it will automatically close the session after the browser is closed.
            self.request.session.set_expiry(0)

            # Set session as modified to force data updates/cookie to be saved.
            self.request.session.modified = True

        # else browser session will be as long as the session cookie time "SESSION_COOKIE_AGE" defined in settings.py
        return super(CustomLoginView, self).form_valid(form)
Enter fullscreen mode Exit fullscreen mode
  • The first thing we did is set the form_class attribute to our custom LoginForm since we are no longer using the default AuthenticationForm.

  • Next we overrode the form_valid method which is called when valid form data has been posted. Inside this method we checked to see whether or not the remember_me check box is checked (a lot of "checks" there, am having a tongue twister:) ).

  • If it's not checked, session will expire automatically when the browser is closed. But for the users who check on the remember_me box, the session will last as long as we define it in settings.py.

  • So let's go ahead and set the SESSION_COOKIE_AGE to 30 days (or as long as you want it to last) in the settings.

settings.py

SESSION_COOKIE_AGE = 60 * 60 * 24 * 30
Enter fullscreen mode Exit fullscreen mode
  • Great. Now inside our main project's urls.py let's map the desired login route to the corresponding CustomLoginView.
  • While we are at it, let's also create the logout route which will be handled by the built in LogoutView.

user_management/urls.py

# Add the following to the list of previous imports
from django.contrib.auth import views as auth_views
from users.views import CustomLoginView  
from users.forms import LoginForm

urlpatterns = [
    # Add this path
    path('login/', CustomLoginView.as_view(redirect_authenticated_user=True, template_name='users/login.html',
                                           authentication_form=LoginForm), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
]
Enter fullscreen mode Exit fullscreen mode
  • redirect_authenticated_user=True means that users who try to access the login page after they are authenticated will be redirected back.

  • Templates aren't part of the resources the auth app gives us, so we need to provide a template both for the login and logout views. By default django looks for these template in registration directory. But we can override this default behavior and tell django to look for login and logout templates inside users/templates/users/ directory. We can do this by passing in the template_name as an argument to as_view function.

  • authentication_form=LoginForm - since we are using our extended login form.

After successful login, by default django redirects the user to a profile page. We can also modify this in our settings.py file, so let's open that up.

settings.py

LOGIN_REDIRECT_URL = '/'
LOGIN_URL = 'login'
Enter fullscreen mode Exit fullscreen mode
  • LOGIN_REDIRECT_URL tells django to redirect the user to the home page after a successful login.
  • The LOGIN_URL is the URL or named URL pattern where requests are redirected for login when we are trying to limit access to certain pages. It defaults to '/accounts/login/'. But since we put our login route at /login, LOGIN_URL tells django where it can find this route.

That's it for part-I of login/logout system. In the next part we will create the templates and modify some stuffs. Stay tuned!

Thanks for your time, you can find the finished app in github.

Feel free to ask, and any suggestions are welcome. See ya!

💖 💪 🙅 🚩
earthcomfy
Hana Belay

Posted on August 27, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related