Security is hard. Often when we build applications we want to allow only registered users to access the application. We want to be able to manage user accounts, see when they last logged in, be able to disable suspicious accounts and have a dashboard to view and manage all this data. We might also decide to support multi-factor authentication and social login. But security isn’t just hard, it also takes a while to implement. What if there’s a service that could take away this part of the development hassle from you? Why spend weeks or months rolling your own auth? This is where Auth0 shines. In this tutorial, I’ll show you how to build a chat application with Pusher, add user authentication with Auth0 Lock, and manage users from the Auth0 dashboard. Introduction to Auth0 and Pusher is an Authentication-as-a-Service (or Identity-as-a-Service) provider focused on encapsulating user authentication and management, which provides an SDK to allow developers to easily add authentication and manage users. Its user management dashboard allows for breach detection and multi-factor authentication, and Passwordless login. Auth0 ’s API’s and hosted infrastructure allow us to build scalable and reliable realtime applications. Pusher has a concept of channels and events which are fundamental to it. Channels provide a way of filtering data and controlling access to different streams of information, while events are the primary method of packaging messages in the Pusher system and form the basis of all communication. Pusher Building the application We will be building a chat application that’ll allow users to communicate with each other where everyone sees every other person’s messages. It’ll work similarly to how channels work in Slack: just one channel for everybody to communicate. Here’s what we’ll be building: Final App Setting up the backend We’ll start by building the backend which will facilitate receiving and broadcasting chat messages, serving static files, and also setting up Auth0 and Pusher. First, you’ll need to signup for a Pusher and Auth0 account. Go to and and sign up for an account. To use Pusher API we have to signup and create a Pusher app from the dashboard. We can create as many applications as we want and each one will get an application id and secret key which we’ll use to initialise a Pusher instance on client or server side code. pusher.com auth0.com Create a new Pusher account To create a new Pusher app, click the side menu, then click the button below the drawer. This brings up the setup wizard. Your apps Create a new app 1. Enter a name for the application. In this case I’ll call it “chat”.2. Select a cluster.3. Select the option “Create app for multiple environments” if you want to have different instances for development, staging and production.4. Select as the frontend and as the backend.5. Complete the process by clicking `Create App` button to set up your app instance. Vanilla JS NodeJS Create new app on Pusher Since we’re building our backend in Node using Express, let’s initialise a new Node app and install the needed dependencies. Run the following command: 1. and select the default options2. to install express and the Pusher node package npm init npm i — save body-parser express pusher Add a new file called which will contain logic to authenticate the Pusher client and also render the static files we’ll be adding later. This file will contain the content below: server.js var express = require(‘express’);var bodyParser = require(‘body-parser’);var Pusher = require(‘pusher’); var app = express();app.use(bodyParser.json());app.use(bodyParser.urlencoded({ extended: false })); var pusher = new Pusher({ appId: APP_ID, key: APP_KEY, secret: APP_SECRET, cluster: eu }); app.post(‘/pusher/auth’, function(req, res) {var socketId = req.body.socket_id;var channel = req.body.channel_name;var auth = pusher.authenticate(socketId, channel);res.send(auth);}); app.post(‘/message’, function(req, res) {var message = req.body.message;var name = req.body.name;pusher.trigger( ‘private-chat’, ‘message-added’, { message, name });res.sendStatus(200);}); app.get(‘/’,function(req,res){res.sendFile(‘/public/index.html’, {root: __dirname });}); app.use(express.static(__dirname + ‘/public’)); var port = process.env.PORT || 5000;app.listen(port, function () {console.log(`app listening on port ${port}!`)}); We instantiate Pusher by passing in an object that contains the details of our app ID and secret key, which can be found on the tab in your Pusher dashboard. Pusher also provides a mechanism for authenticating users to a channel at the point of subscription. To do this, we expose an endpoint on the server that will validate the request and respond with a success or failure. This endpoint will be called by Pusher client libraries and can be named anything. We used the default name for this endpoint on Pusher, which is . The line authenticates the client with Pusher and returns an authentication code to the calling client. App Keys /pusher/auth var auth = pusher.authenticate(socketId, channel); To allow this file to run when we start npm, we update with the following value: package.json “scripts”: {“start”: “node server.js”,“test”: “echo \”Error: no test specified\” && exit 1"} To create an Auth0 client Create an Auth0 client 1. Select from the side menu.2. On the new page, click the button3. Enter a name for the app and select as an option4. Click the button to create the client. Clients Create Client Single Page App Create An Auth0 client provides us with Client Id and Secret which we’ll use to interact with Auth0 from the code. On the settings tab, we can see the Name, Client Id, Secret, Client Type and many more. I want to enable CORS for my domain , set the log out URL and the URL to redirect to after the user has been authenticated with Auth0. Update the following settings with http://localhost:5000 http://localhost:5000 1. Allowed Callback URLs2. Allowed Logout URLs3. Allowed Origins (CORS) Building the frontend With the backend all good to go, we build the web page that will facilitate messaging. Create a folder named which will contain the html and javascript file. Create two new files and with the following content: public style.css index.html style.css url(" ");.chat{list-style: none;margin: 0;padding: 0;}.chat li{margin-bottom: 10px;padding-bottom: 5px;border-bottom: 1px dotted #B3A9A9;}.chat li.left .chat-body{margin-left: 60px;}.chat li.right .chat-body{margin-right: 60px;} @import http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css .chat li .chat-body p { margin: 0; color: #777777; } .panel .slidedown .glyphicon, .chat .glyphicon { margin-right: 5px; } .body-panel { overflow-y: scroll; height: 250px; } ::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); background-color: #F5F5F5; } ::-webkit-scrollbar { width: 12px; background-color: #F5F5F5; } ::-webkit-scrollbar-thumb { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); background-color: #555; } index.html <!-- template from --><!DOCTYPE html><html><head><!-- Latest compiled and minified CSS --><link rel="stylesheet" href=" " integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"><!-- Optional theme --><link rel="stylesheet" href=" " integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"><scriptsrc=" "integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="crossorigin="anonymous"></script><!-- Latest compiled and minified JavaScript --><script src=" " integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script><link rel="stylesheet" href="style.css"><script src=" "></script><script src=" "></script><script src="index.js"></script></head><body><div class="container"><div class="row form-group"><div class="col-xs-12 col-md-offset-2 col-md-8 col-lg-8 col-lg-offset-2"><div class="panel panel-primary"><div class="panel-heading"><span class="glyphicon glyphicon-comment"></span> <span id="username"></span><div class="btn-group pull-right"><button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-chevron-down"></span></button><ul class="dropdown-menu slidedown"><li><a><span class="glyphicon glyphicon-refresh"></span>Refresh</a></li><li><a><span class="glyphicon glyphicon-ok-sign"></span>Available</a></li><li><a><span class="glyphicon glyphicon-remove"></span>Busy</a></li><li><a><span class="glyphicon glyphicon-time"></span>Away</a></li><li class="divider"></li><li><a id="logout"><span class="glyphicon glyphicon-off"></span>Sign Out</a></li></ul></div></div><div class="panel-body body-panel"><ul class="chat"> http://bootsnipp.com/snippets/6eWd https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css https://code.jquery.com/jquery-2.2.4.min.js https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js https://cdn.auth0.com/js/lock/10.18.0/lock.min.js https://js.pusher.com/4.0/pusher.min.js </ul> </div> <div class="panel-footer clearfix"> <textarea id="message" class="form-control" rows="3"></textarea> <span class="col-lg-6 col-lg-offset-3 col-md-6 col-md-offset-3 col-xs-12" style="margin-top: 10px"> <button class="btn btn-warning btn-lg btn-block" id="btn-chat">Send</button> </span> </div> </div> </div> </div> </div> <script id="new-message" type="text/template"> <li id="{{id}}" class="right clearfix"> <div class="chat-body clearfix"> <div class="header"> <small class="text-muted">{{name}}</small> </div> <p> {{body}} </p> </div> </li> </script> </body> </html> This file uses template from and also includes a script reference to Auth0 Lock . is a drop-in authentication widget that provides a standard set of behaviours required for login and a customisable user interface. It provides a simple way to integrate with Auth0 with very minimal configuration. bootsnip <script src=” https://cdn.auth0.com/js/lock/10.18.0/lock.min.js "></script> Lock We want to allow users to sign in when they enter the application and be able to send messages once they’re authenticated. Add a new file with the following content: index.js $(document).ready(function(){// Initiating our Auth0Locklet lock = new Auth0Lock(‘CLIENT_ID’,‘CLIENT_DOMAIN’,//example: lotus.auth0.com{auth: {params: {scope: ‘openid profile’}},autoclose: true,closable: false,rememberLastLogin: true}); let profile = JSON.parse(localStorage.getItem(‘profile’));let isAuthenticated = localStorage.getItem(‘isAuthenticated’); function updateValues(userProfile, authStatus) {profile = userProfile;isAuthenticated = authStatus;} if(!isAuthenticated && !window.location.hash){lock.show();//show Lock widget} // Listening for the authenticated eventlock.on(“authenticated”, function(authResult) {// Use the token in authResult to getUserInfo() and save it to localStoragelock.getUserInfo(authResult.accessToken, function(error, profile) {if (error) {// Handle errorreturn;} localStorage.setItem(‘accessToken’, authResult.accessToken);localStorage.setItem(‘profile’, JSON.stringify(profile));localStorage.setItem(‘isAuthenticated’, true);updateValues(profile, true);$(“#username”).html(profile.name);});});}); We initialise Lock by passing it the Client Id of the app, your user domain which starts with your username followed by or e.g . The widget is configurable and we can send in configuration options like , , and . Within the option we tell it to return the and claims. .auth0.com {YOUR_SELECTED_REGION}.auth0.com lotus.eu.auth0.com closable autoClose auth auth openid profile We check if the user is authenticated and show the widget when they’re not. Once the user is authenticated, Lock emits the `authenticated` event which we’ve subscribed to. When it’s raised, we store the user profile and other credentials to localStorage and set the user’s name to be displayed on the page. Once the user is authenticated, we want to connect to Pusher and send messages across. Update index.js with the following code: if(!isAuthenticated && !window.location.hash){lock.show();}else{ // Enable pusher logging — don’t include this in productionPusher.logToConsole = true; var pusher = new Pusher(‘APP_SECRET’, {cluster: ‘e.g eu’,encrypted: false}); var channel = pusher.subscribe(‘private-chat’);channel.bind(‘message-added’, onMessageAdded);} function onMessageAdded(data) {let template = $(“#new-message”).html();template = template.replace(“{{body}}”, data.message);template = template.replace(“{{name}}”, data.name); $(“.chat”).append(template);} Pusher is initialised with the and which you can get from the app dashboard on Pusher. We subscribe to a channel called . Pusher has 3 types of channels: Public, Private and Presence channel. Private and Presence channels let your server control access to the data you are broadcasting. Presence channels go further to force subscribers to register user information when subscribing. Private channels are named starting with and authenticated in the server when subscribing. APP_SECRET CLUSTER private-chat private- And finally we want to send the message to the user when they click send and also log them out when they select signout. Update with the code below index.js $(‘#btn-chat’).click(function(){const message = $(“#message”).val();$(“#message”).val(“”);//send message$.post( “ ”, { message, name: profile.name } );}); http://localhost:5000/message $(“#logout”).click((e) => {e.preventDefault();logout();}); function logout(){localStorage.clear();isAuthenticated = false;lock.logout({returnTo: “ ”});} http://localhost:5000 When the user clicks the send button, we take the message and put it in an object with the user’s profile name and send it to the endpoint on the server. When the logout button is clicked, it calls the logout function which clears the data stored in localStorage and call which logs the user out on Auth0 and redirects them back to our website. With all these additions, index.js should have the following content: /message lock.logout() $(document).ready(function(){// Initiating our Auth0Locklet lock = new Auth0Lock(‘CLIENT_ID’,‘CLIENT_DOMAIN’,{auth: {params: {scope: ‘openid profile’}},autoclose: true,closable: false,rememberLastLogin: true}); // Listening for the authenticated eventlock.on(“authenticated”, function(authResult) {// Use the token in authResult to getUserInfo() and save it to localStoragelock.getUserInfo(authResult.accessToken, function(error, profile) {if (error) {// Handle errorconsole.log(error);return;} localStorage.setItem(‘accessToken’, authResult.accessToken);localStorage.setItem(‘profile’, JSON.stringify(profile));localStorage.setItem(‘isAuthenticated’, true);updateAuthenticationValues(profile, true);$(“#username”).html(profile.name);});}); let profile = JSON.parse(localStorage.getItem(‘profile’));let isAuthenticated = localStorage.getItem(‘isAuthenticated’); function updateAuthenticationValues(userProfile, authStatus) {profile = userProfile;isAuthenticated = authStatus;} $(“#logout”).click((e) => {e.preventDefault();logout();}); function logout(){localStorage.clear();isAuthenticated = false;lock.logout({returnTo: “ ”});} http://localhost:5000 function onMessageAdded(data) {let template = $(“#new-message”).html();template = template.replace(“{{body}}”, data.message);template = template.replace(“{{name}}”, data.name); $(“.chat”).append(template);} if(!isAuthenticated && !window.location.hash){lock.show();}else{if(profile){$(“#username”).html(profile.name);} // Enable pusher logging — don’t include this in productionPusher.logToConsole = true; var pusher = new Pusher(‘APP_SECRET’, {cluster: ‘eu’,encrypted: false}); var channel = pusher.subscribe(‘private-chat');channel.bind(‘message-added’, onMessageAdded); $(‘#btn-chat’).click(function(){const message = $(“#message”).val();$(“#message”).val(“”);//send message$.post( “ ”, { message, name: profile.name } );});}}); http://localhost:5000/message To test the app, run `npm start` on the terminal and open on two separate browsers. Here’s a run through of it: http://localhost:5000 Wrap Up This is an app to show how you can use Pusher to send messages in real-time and secure the channels, add user authentication and account management with Auth0, and easily integrate to Auth0 using Auth0 Lock. On your auth0 you can see the total number of users, logins and new signups. dashboard You can also see all your users when you click on the **Users** side menu. On this page you can see the list of your users and their mode of login. Selecting a user takes you to a more detailed page where you can take various actions on the account, for example, blocking an account or sending a verification email. Also on Pusher, you can go to your application dashboard, under the , where you’ll see statistics concerning your application, such as connection frequency and how many messages were sent through that app. The combination of these two technologies makes it faster and easier to build real-time secured applications. You can find the code here on . Stats GitHub This was originally published on Pusher