This system works well but does have several areas for improvement. Some of them are as follows.
1. Authentication: Currently, anyone can control your LED if they have the right URL. That might be okay if the Pi can only be accessed on your network and you trust everyone connected to it, but it still could be helpful to have a login feature that requires a username and password before anyone can turn the LED on and off.
2. HTTPS and WSS: currently your website is being served over http and the web socket connection is ws. You may have heard of http, but perhaps not ws. Both are web protocols, http being for websites and ws being for web socket connections. Both are unencrypted though, and if you were to open up wireshark you could see every single message being sent out by the Pi and whatever device you were controlling it with. To change this, you will have to upgrade the setup to https and wss, which are the encrypted forms of both of those protocols.
3. Router DNS Settings: To make it so that you don’t have to put in the IP address of your Pi every time you want to turn the LED on and off, it would be helpful to change the DNS settings on your router so that a URL like mypi.me or whatever you choose is routed to your Pi.
4. Broadcasting to Global Network: You cannot connect to the Pi and control the light from any device that is not on the same private WiFi network as your Pi. This should be okay in most use cases, as it isn’t too likely that you will need to be controlling an LED from the other side of the globe, but if you do want that kind of functionality, you will have to port forward it by messing with router settings.
5. Beyond LED’s: The webpage control is cool and all, but it is just turning an LED on and off. That’s no fun, right? Well, because you can put whatever you want in the JSON being sent to the Pi, and you can even send messages to the browser(6), it is entirely possible to expand your code out to controlling motors, monitoring sensors, and much more.
6. CSS Makeover: Plain HTML does not look all that good, and so if you want something with a little more zest then you will need to make some .css files to style the page. You can find a good tutorial on modifying the checkbox to look like a toggle switch here(7).
If none of these are a problem for you, or you don’t want to work on them right now, then that’s all good. Depending on what you want to do they may not even be downsides. In that case you can stop right here and enjoy the rest of your day.
If you wish to go further and dive deeper into this project, then continue reading. The rest of this module covers the process of implementing number 1 on the list by creating an authentication system using multiple users. Numbers 2 through 5 are beyond the scope of what we will be covering in this module, but if you read further there are some brief explanations of the concepts involved along with resources to look to if you wish to pursue any of those routes.
Before we get into the code of making our sign in feature, we need to cover what happens when you create a username and password on a website. When you create an account, your username is stored on a database somewhere, but your password is not. Instead, your password is put through something called a hash function(8) to get a large integer number that is usually written in hexadecimal, and is then stored on the database. Then, when you later sign in, the string that you put into the password field is hashed before being checked against the hash in the database. This is all done to increase security by ensuring that your passwords are never stored in plain text.
There are many different hash functions out there, some of them more secure than others. Some like MD5 of SHA1 have vulnerabilities such as collision, which is where multiple strings end up having the same hash. This can make passwords easier to crack because it increases the likelihood of a brute force attack succeeding. For our purposes, we will be using the SHA256(9) algorithm, which is a very fast and secure algorithm with no known vulnerabilities.
The first step will be making our web socket support authentication. Essentially, we will have a username and password field on the website, as well as a sign in button. The password will be hashed on the client side, and then the username and password will be sent to the server side and validated there. To make the connection secure, our server will require that the first message sent is credentials. If the credentials are found invalid too many times, then the web socket connection will be closed by the server.
When validating credentials, the server check database in which each username and its associated hashed password is stored. If the credentials sent by the client match any of the user entries on the database, then the server will tell the client and open the connection to receive messages controlling the LED.
Altogether it is a simple system, but there is a decent amount of code to write, so just take your time working through it all.