Thank you following me on this small journey regarding the implementation of login functionality with React-Native. I am hoping this will be the last tutorial of the lot and it doesn’t drag out too much further. So in this tutorial I will be focusing on the “signin” endpoint within the API as well as testing this endpoint in postman.

Ok we shall start with opening up our API again and make a new “POST” endpoint named “signin” with a callback function.

app.post('/signin',function(req,res){});

I will again create 2 variables within this endpoint of email and password which will passed into the API through a request body from our app.

var email = req.body.email;var password = req.body.password;

I will then get a connection from the pool, do the regular error checks like we have done in the previous articles and use these variables to first see if there is an account with the entered email using the keyword “query” to contain the SQL I want to use and if there is a result returned from my “query” callback I will progress and retrieve the password and userID from user table using another “query”. Furthermore I will use bcrypt to compare the entered password against the one stored and if they are both the same (bcrypt does some intelligent stuff in that it knows when a salted password is the same as one entered in plain text) then I will use the package “jwt” to sign a unique JWT with the user ID and send that back to the app.

So far this is what I have for my “signin” endpoint.

app.post('/signin',function(req,res){var email = req.body.email;var password = req.body.password;myPool.getConnection(function(err,myConnection){if(err){res.send({message:'Error retrieving connection: ' + myConnection})}else{myConnection.query('SELECT COUNT(*) AS EmailCount FROM user WHERE email = ?',[email],function(err,emailCountResults,emailCountFields){if(err){res.send({message:'Error selecting count: ' + err})}else{}})}})});

In the empty else statement we will create a variable equal to the “EmailCount” column selected from the previous query, if this is 1 then we will begin to do another query to select the userID and password , else we respond with a message saying “No account associated with that email”.

var emailCount = emailCountResults[0].EmailCount;if(emailCount===1){myConnection.query('SELECT UserID,password FROM user WHERE email = ?',[email],function(err,idPassResults,idPassFields){if(err){res.send({message:'Error selecting user info: ' + err});}else{}})}else{res.send({message:'No account associated with that email'});}

So now my else statement looks like the above where if the email is present in the database then we select the UserID and password.

We then set the retrieved UserID and password equal to variables.

After this we use bcrypts built in method “compare” which compares a plain text password passed into the FIRST parameter against the salted password from the database in the SECOND parameter, a promise is then used to do something which contains one argument “result”. If “result” is true then that means the passwords are the same and we can progress, else, an incorrect password has been entered.

let userPassword = idPassResults[0].password;let userID = idPassResults[0].UserID;bcrypt.compare(req.body.password,userPassword).then((result)=>{if(result){//if the passwords are the same}})

If the passwords are the same this is where we begin the process of responding to the user with a JWT.

We will do this using the “jsonwebtoken” package and the method “sign”.

However, there is one additional step we must take we need to pass in a secret key with our JWT.

Now go to the link below.

https://www.grc.com/passwords.htm

Going to this link will generate a few secure passwords for you which will show on the screen. Copy the values underneath the “64 random hexadecimal characters (0–9 and A-F):” and go to your “config vars” section which can be found in “settings” in Heroku and create a config var with a key of “SECRETKEY” in your code you will then reference this config var using “process.env.SECRETKEY”.

Once you have saved this ensure your code inside of the latest else is similar to the below. Albeit a few variables/column names may be different.

let userPassword = idPassResults[0].Password;let userID = idPassResults[0].UserID;bcrypt.compare(req.body.password,userPassword).then((result)=>{if(result){//if the passwords are the sameconst token = jwt.sign({userID: userID }, process.env.SECRETKEY, {expiresIn: '1h'});}})

We have now passed in our secret key to our JWT and will send this JWT back to our user with the user ID which is unique to that user, if the user gets this back they will be redirected to the home page of the app when we have incorporated the necessary changes to the navigators in our react-native app.

let userPassword = idPassResults[0].password;let userID = idPassResults[0].UserID;bcrypt.compare(req.body.password, userPassword).then((result) => {if (result) {//if the passwords are the sameconst token = jwt.sign({ userID: userID }, process.env.SECRETKEY, {expiresIn: '1h'});res.status(200).send({ token: token });}else{res.sendStatus(401).send({ token: token });}})

Note

PLEASE READ THIS — There may be one issue that you when face when you begin testing this after you git add, commit and push and that might be that when you test the “signin” endpoint on postman it will always return false for the “bcrypt.compare” you may need to go back to your password column in your database and change its length as I set mine to 45 characters and that got cut off when selecting the password from the db to compare. I have changed mine to VARCHAR(500) and my signin works fine now! Just thought I would say.

Ok so once you have done all of your committing and pushing to master go and sign up to your app using the “signup” endpoint and then test out the signin with the “signin” endpoint.

Voila!

There we go, I have used the “signin” endpoint using the correct email and password and it returned a token.

Whereas if I enter an incorrect password I get a response of unauthorized.

Thank you for reading all the way through if there is anything I have missed then please let me know and I will amend the article accordingly, I hope you learned something from this and don’t forget to share/like the article too!

Software Developer in the UK. With a keen passion for React Native.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store