We’re going to kick off chatire by Implementing User Management and Authentication so users can create accounts and login.
Thanks to Django’s excellent and vibrant community, most of the work has been done for us. Hence we’re going to make use of a third-party django library called djoser
Let’s get it from
Djoser is a REST Implementation of Django’s inbuilt authentication system. So instead of forms and views that return html, it provides us with REST endpoints for user registration, token creation, user management etc.
We’re going with the simplest setup possible for djoser. Include the following in your
add djoser’s urls to
rest_framework.authentication.TokenAuthentication to django rest framework’s authentication classes:
Lastly, run the database migrations with
python manage.py migrate this would create the tables that are required by
That’s it! The authentication endpoints are now available for use. Let’s create a new user:
Voila! we have a new user. Check out the djoser docs for the list of available endpoints and how to use them http://djoser.readthedocs.io/en/latest/base_endpoints.html
One of the reasons is it’s gentle learning curve, It’s very easy to get started and unlike React you don’t need a build pipeline (with Webpack and co) to build a production ready app. You can just include an external
<script> tag like you would do with
It also has a Vibrant community with lot of plugins and tutorials available on the web.
We’ll make use of
vue-cli to quickly create a Vue app (instead of the
<script> tag method). This method allows us to leverage the full power of
ES6+ and single file Vue components.
vue-cli from npm:
Let’s scaffold a new project based on the webpack template with
NoTE: Make Sure you select the “install vue-router” option
This might be the right time to grab a coffee or a quick snack because this might take sometime depending on your network speed. Our ISP’s are Really terrible in Nigeria. it took over 10 minutes.
After that navigate to the new vue app and run the dev server with:
npm run dev.
You should see this when you access
Let’s talk about the folder structure a little:
build: This directory contains script that are used to run the webpack developement server or bundle the application when you’re ready to deploy to production. For example, The
npm run devcommand actually runs this:
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
--inlineoption injects the generated static files into our
config: Just like the name says, this you should store configuration values for development, testing and production
src: This is where we’ll be writing most of our code, it contains subfolders for different aspects of our application.
Our single file components would be placed inside this folder. There’s already a default
index.jsfile in the router folder contains the configuration for vue-router
The tests can be run with
npm run unit(For unit tests) and
npm run e2efor End to end tests.
vue-cli also sets up hotreloading for us which really improves the developer’s experience. As soon as you hit save after editing a component, the change is immediately reflected in the browser.
Configure Vue router
Create two components in the
components folder. One for the main chat screen callled
Chat.vue and another for User Authentication and Signup we’ll call that
Ideally what we want is to conditionally display the components based on the Login status of the user. If the User is Authenticated, we want to display the Chat component else we want them to either signup or login which means we’ll display the
We can do this by creating a implementing a global navigation. Edit the router’s
index.js file to include the following
beforeEach guard is called before a navigating to any route in our application.
If a token is stored in the
sessionStorage we allow the navigation to proceed by calling
next() else we redirect to the auth component.
No matter the route a user navigates to in our application this function will check if the user has an auth token and redirect them appropraitely.
I’ve built a simple Login/Signup page with Bootstrap 4 tabs, this is the content of
In the snippet above,
We also created event listeners on both forms using
@submit.prevent that’ll listen to the form submit event of each form and call the methods specified. We haven’t implemented these methods yet.
Since we’re making use of
Bootstrap, instead of installing
npm we defined a variable
$ that points to the globally registered
jQuery’s ajax methods to communicate with the django server. Feel free to use another ajax library like Axios if you want to decouple your application from
jQuery. It’s pretty popular among
The page should look like this:
Let’s Grab our auth token
We want to sign the user up and then redirect them to the Chat route.
To acheive that, we have to implement the
signIn methods we specified earlier:
Now try and submit the form. Oops! It failed with:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/auth/users/create. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Quoting the mozilla developer’s site:
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to let a user agent gain permission to access selected resources from a server on a different origin (domain) than the site currently in use. A user agent makes a cross-origin HTTP request when it requests a resource from a different domain, protocol, or port than the one from which the current document originated.
Basically It’s a mechanicsm that subverts the same origin policy. The same origin policy is what prevents a website on a different domain from making a
XmlHttpRequest (Ajax) to another website/webservice. You can use CORS to weaken the security mechanicsm a little and tell the webserver that it’s safe to allow Ajax requests from a particular domain(s).
In our case, even though both webservers are running on localhost, due to the fact that they’re on different ports (8080 and 8000) they’re seen as different domains.
For the domains to match the scheme (
https), hostname (
localhost) and the port must match.
So how do we enable CORS in our django application? There is third-party app we can install to do that called
add it to your
Include the middleware, (Make sure it comes before
CORS_ORIGIN_ALLOW_ALL = True
Note that this enables CORS for all domains. This is fine for development but when you’re in production you only want to allow certain domain(s) this can be controlled with:
Read the django-cors-header documentation to find out about other options.
After doing this, you should be able to create an account and sign in immediately.
Behnind the scenes,
django-cors-headers uses a Middleware to add appropriate headers to each request that tells Django that the request is safe and it should be allowed.
Because we use
sessionStorage to store the auth token, we can start a new session by opening a new browser tab.
To actually persist the token between browser restarts/new tabs you can switch to
It has the same api as the
sessionStorage so you’re just changing
Then you can create a function that removes the token from the storage you decide to stick with by calling
removeItem. This is how we would do it for
That’s all for this part, Our goal was to built a simple User managment and auth system. We started out by installing djoser which is an excellent third party django app that provides
REST endpoints for authentication.
We also saw how we could use
jQuery’s ajax methods to call those endpoints from Vue.
On the road to victory, we were stopped by
Same origin policy and we briefly talked about why it exists. Eventually we learnt how to allow Ajax requests from the Vue app to the django backend using
In the next part, we’ll build the django models and API for the Chat app.