Object Oriented Programming

Ngoding Bareng : 2 Factor Authentication – 2FA – untuk keamanan login pada mobile aplikasi dengan Android Studio & Node JS

Akan dibawakan pada workshop di Binus Bekasi – Jumat, 22 November 2019. Lab Komputer R.317 Lantai 3. Pukul 13:20 – 15:00 WIB.

Apa sih 2FA ?

2FA adalah suatu fitur keamanan yang difungsikan sebagai verifikasi apakah pengguna yang akan login benar – benar orang yang memiliki akun tersebut. Pada workshop kali ini kita akan mencoba mencocokan password dan dilanjutkan verifikasi menggunakan sms pada mobile apps android.

Butuh Software / Aplikasi Apa aja?

  • Mysql Server dan Mysql Client tools, digunakan untuk database. Mungkin bisa pakai paket mysql dengan phpmyadmin seperti : Xampp pada windows, Lampp pada Linux atau paket lainnya. Link Download : https://www.apachefriends.org/download.html
  • Android Studio beserta SDK dan Emulator digunakan sebagai Development tools Android, pada materi kali ini akan menggunakan bahasa pemrograman Java. Link Download : https://developer.android.com/studio
  • Nodejs , akan digunakan sebagai server backend di pc local. Link download : https://nodejs.org/en/download/
  • Notepad ++ , akan digunakan untuk editor nodejs code. Link Download : https://notepad-plus-plus.org/downloads/

Persiapan Pertama : Akun Twilio ( Trial )

Persiapan pertama adalah membuat akun pada sms gateway provider. pada materi kali ini saya menggunakan twilio di mana kita bisa membuat akun trial sebagai uji coba. Apabila twilio ini sudah sesuai dengan kebutuhan klien atau perusahaan maka buatlah akun resminya.

Langkah nya :

  1. Buka https://www.twilio.com , Sign up

2. Anda akan memiliki akun trial twilio, catat credential nya.

twilio credential

Persiapan Kedua : Database Mysql

Anda bisa membuka mysql client, atau misalkan phpmyadmin dan eksekusi DDL mysql berikut :

Buat database smslogin

CREATE DATABASE `smslogin`
    CHARACTER SET 'latin1'
    COLLATE 'latin1_swedish_ci';

Buat tabel token_sms, Untuk menyimpan token yang digenerate dan akan di cocokkan :

USE `smslogin`;
CREATE TABLE `token_sms` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `token` varchar(200),
  `user_id` bigint(20),
  `date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Buat tabel user, yang akan digunakan untuk menyimpan email, password dan token aktif :

USE `smslogin`;
CREATE TABLE `user` (
  `user_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `email` varchar(200) DEFAULT NULL,
  `passwd` varchar(100) DEFAULT NULL,  
 `phone_number` varchar(20),
  `token` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`user_id`),
  KEY `email` (`email`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Insert data contoh untuk login ke tabel user :


INSERT INTO `user` (`email`, `passwd`,`phone_number`) VALUES ( 'dimas@campaign.com', 'abc','+6288686xxxx');

Persiapan Ketiga : Installasi backend nodejs library

Buat folder, didalamnya ada file app.js, melalui command prompt masuk ke folder tersebut dan kemudian :

npm install mysql

npm install twilio

npm install express

npm i twilio

Persiapan Ke empat : Pemahaman Project Flow

Authentikasi Email dan Password

Flow Halaman Pertama Frontend & Backend

Authentication 6 digit sms :

Halaman Kedua Auth 6 digit Frontend & Backend

Let’s Start Coding….Mulai dari backend

Buat coding di app.js seperti dibawah ini, yang pada intinya membuat 2 fungsi url : /login/ dan /smsauth/


'use strict';
// [START app]
const express = require('express');
var bodyParser = require('body-parser');
var Twilio = require('twilio');
const app = express();
var jsonParser = bodyParser.json();
var urlencodedParser = bodyParser.urlencoded({ extended: true });
app.use(jsonParser);
app.use(urlencodedParser);
 const accountSid = 'Account_SID_Anda';
const authToken = 'Auth_Token_AKUN_TWILIO_ANDA';
 var twilio = new Twilio(accountSid, authToken);
var mysql = require('mysql');
 
var conbeta = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "",
  database: "smslogin" 
});

conbeta.connect(function(err) {
  if (err) throw err;
  console.log("Connected!");
});

app.get('/', (req, res) => {
  res.status(200).send('Hello, world!').end();
});
//======loop get username and prof_id

app.post('/login/',function(req,res){
  var snapshot=req.body;
  //get params from android volley
  var key_secret="";  
  var key_ori = "ok12345&#";   
  var username="";    
  var pass="";   
  if (snapshot.username!=null){username=snapshot.username;} 
  if (snapshot.pass!=null){pass=snapshot.pass;} 
  if (snapshot.key_secret!=null){key_secret=snapshot.key_secret;}
  
  if (username!="" && pass!="" && key_ori == key_secret){
    console.log('username lewat = '+username);
    var check = "SELECT * FROM  `user` ";
        check = check+"where `email`='"+username+"'";
        conbeta.query(check, function (err, result) {
			 console.log(result);
          console.log(result.length);
            if (result.length>0){
				//username ketemu
				
               result.forEach(userlogin => {
								
var passfromdb = `${userlogin.passwd}`;
								if(passfromdb ==pass){
									//password sesuai
var digit1 = Math.floor((Math.random() * 10));
var digit2 = Math.floor((Math.random() * 10));
var digit3 = Math.floor((Math.random() * 10));
var digit4 = Math.floor((Math.random() * 10));
var digit5 = Math.floor((Math.random() * 10));
 var digit6 = Math.floor((Math.random() * 10));
var smstoken =  digit1 +""+ digit2+"-"+digit3+""+digit4+"-"+digit5+""+digit6;
									 twilio.messages
										.create({
											  body: 'hello auth code ' + smstoken,
											  from: '+1_No_Telepon_Twilio_Anda',
											  to: `${userlogin.phone_number}`
											})
										   .then(message => console.log(message.sid))
										   .done();
										   
										     var sql = "Insert into token_sms(user_id,token,date) ";
												sql = sql+"values('"+ `${userlogin.user_id}`+"','"+smstoken+"',CURRENT_TIMESTAMP());";
												conbeta.query(sql, function (err, result) {
												});
									 res.send({ data: '0||'+`${userlogin.user_id}` });
								}else{
									//password tidak sesuai
									
									 res.send({ data: '2' });
									
								}
								 
				});

            }else{

          
				  //username tidak ketemu
				  res.send({ data: '1' });
				  
				  
			  };
     });

                // res.send({ data: 'success' });
  }else{
    res.send({ data: 'failed token' });
  }
});

 
 
  

app.post('/smsauth/',function(req,res){
  var snapshot=req.body;
  var key_secret="";  
  var key_ori = "ok12345&#";   
  var user_id="";    
  var token="";   
 
  if (snapshot.user_id!=null){user_id=snapshot.user_id;} 
  if (snapshot.token!=null){token=snapshot.token;} 
  if (snapshot.key_secret!=null){key_secret=snapshot.key_secret;}
  
  if (user_id!="" && token!="" && key_ori == key_secret){
    console.log('token lewat = '+token);

 

    var check = "SELECT * FROM  `token_sms` ";
        check = check+"where `user_id`='"+user_id+"' and  date between timestamp(DATE_SUB(NOW(), INTERVAL 1 MINUTE)) AND timestamp(NOW())  order by date DESC limit 0,1";
        conbeta.query(check, function (err, result) {
			 console.log(result);
          console.log(result.length);
            if (result.length>0){
				//username ketemu
				
               result.forEach(userlogin => {
								var tokenfromdb = `${userlogin.token}`;
								var tokendbclear = tokenfromdb.replace("-","");
								var tokenclear = token.replace("-","");
								if(tokendbclear ==tokenclear){
									//password sesuai
									 
										   
										     var sql = "update user set  token = '" + tokenfromdb + "' ";
												sql = sql+"where `user_id`='"+user_id+"' ";
												conbeta.query(sql, function (err, result) {
												});
									 res.send({ data: '0||'+`${userlogin.user_id}` });
								}else{
									//token tidak sesuai
									
									 res.send({ data: '2' });
									
								}
								 
				});

            }else{

          
				  //username tidak ketemu
				  res.send({ data: '1' });
				  
				  
			  };
     });

                // res.send({ data: 'success' });
  }else{
    res.send({ data: 'failed token' });
  }
});

 

// Start the server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});
// [END app]
 

Testing Fungsi Backend

Bisa menggunakan aplikasi REST API pada google chrome atau postman :

berhasil mengirim sms

Mulai ngoding Frontend

Buka Android Studio, untuk menghemat waktu saya sudah membuat template project Android Studio yang bisa di download : https://drive.google.com/file/d/1SqBcY8tJvg8k27SVtr-uSmbVlG6toHpT/view?usp=sharing

Download, extract kemudian buka project diatas menggunakan android studio. Penjelasan detail akan diberikan saat workshop. Point yang perlu di perhatikan adalah pada build.gradle di app, library yang digunakan antara lain volley dan butterknife. kemudian perhatikan file XML untuk tampilan dan Java nya berfungsi sesuai dengan flow yang dijelaskan sebelumnya.

====

Selamat Mencoba….. 🙂


Referensi Frontend :

https://github.com/sourcey/materiallogindemo

https://jakewharton.github.io/butterknife/

http://www.itsalif.info/content/android-volley-tutorial-http-get-post-put

Referensi Apabila Backend Menggunakan php :

https://www.twilio.com/docs/libraries/php

https://github.com/twilio/twilio-php

Referensi Apabila Backend Menggunakan Nodejs :

https://www.twilio.com/docs/libraries/node

https://github.com/twilio/twilio-node

https://www.petanikode.com/nodejs-mysql/

Leave a Reply

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