Building My Own Login System: Python Falcon Corona SDK Lua Material UI

In my last post I discussed how to handle long HTTP request processes using asynchronous workers (Celery and RabbitMQ). In this post, I am going to describe the login system that I have set up for my app. Look at my previous posts for more information on the Python Falcon framework I am using or the Corona SDK and Lua setup on the front-end.

Instead of using Google or Facebook login, I decided to implement my own login system. I can always add Google or Facebook authentication later in addition to my own login system if I want. To start, I added three text input boxes on a login page: one for username, one for email, and one for password. Here is the Material UI Lua code to do that:

mui.newTextField({
parent = sceneGroup,
name = “email”,
labelText = “Email”,
text = “”,
font = native.systemFont,
width = mui.getScaleVal(500),
height = mui.getScaleVal(70),
x = display.contentWidth/2,
y = mui.getScaleVal(300),
activeColor = {0,0,0,1},
inactiveColor = { 1, 1, 1, 1 },
callBack = mui.textfieldCallBack,
fontSize = mui.getScaleVal(40)
})
mui.newTextField({
parent = sceneGroup,
name = “password”,
labelText = “Password”,
text = “”,
font = native.systemFont,
width = mui.getScaleVal(500),
height = mui.getScaleVal(70),
x = display.contentWidth/2,
y = mui.getScaleVal(450),
activeColor = {0,0,0,1},
inactiveColor = { 1, 1, 1, 1 },
callBack = mui.textfieldCallBack,
fontSize = mui.getScaleVal(40),
isSecure = true
})

mui.newTextField({
parent = sceneGroup,
name = “username”,
labelText = “Username”,
text = “”,
font = native.systemFont,
width = mui.getScaleVal(500),
height = mui.getScaleVal(70),
x = display.contentWidth/2,
y = mui.getScaleVal(600),
activeColor = {0,0,0,1},
inactiveColor = { 1, 1, 1, 1 },
callBack = mui.textfieldCallBack,
fontSize = mui.getScaleVal(40)
})

Next, I created a submit button that would post the data (via HTTPS) to the login endpoint on my server. Once the data is posted, I salt and encrypt the password server side instead of client side. Code below:

class SubmitLogin(object):
def on_post(self, req, resp):
resp.status = falcon.HTTP_200
email = req.get_param(“email”)
password = req.get_param(“password”)
username = req.get_param(“username”)
hashed = bcrypt.hashpw(password.encode(‘utf-8’), bcrypt.gensalt(1000))

The bcrypt hashpw function is a good encryption algorithm to use (according to my security aware friends) and they recommended 1000 rounds. Then, I inserted the user information into my database.

Next, I needed to implement a password check API endpoint for when people would come back to login. Using similar code as above, I created a login screen (the other screen I created was a sign-up page), and posted the login parameters to my check login API endpoint. Code to test password below:

test = bcrypt.checkpw(password.encode(‘utf-8’), user[“password”])

At this point, I can sign-up users and check if their login is correct. This is good, but they would still have to login every single time they open the app. So I am going to store a session variable on their device and then renew the session every few days. If they have the correct session variable on their device, they do not need to login and they will automatically be authenticated into the app. To do this, I created a session check API endpoint that will receive a session token and test if this token is associated with the user submitting the session token. If the session token matches, the user will be authenticated. If not, they will have to login again. The code on the front-end to save this session token can be found below:

local loadsave = require( “loadsave” )
loadsave.saveTable(userSessionInfo, “userSessionName.json”)

Then, once the data in userSessionInfo is saved, it can be accessed at any time in the application by loading the userSessionName.json file.

And that’s it for this post. I can now sign-up users, log them in successfully, and create and store session variables so that users don’t have to login every time they want to use the app.

Leave a Comment

Your email address will not be published. Required fields are marked *

css.php