จากโพสที่แล้ว ตัวอย่างการพัฒนา API บน Firebase Cloud Function ด้วย NodeJS และ ExpressJS ในโพสนี้เราจะเพิ่ม การทำ Token Authentication สำหรับความปลาดภัยในการทำ REST API โดย Firebase และ NodeJS โดยมีขั้นตอนดังนี้
1. เพิ่ม Module jsonwebtoken
โดยพิมพ์คำสั่ง npm install jsonwebtoken
2. แก้ code ไฟล์ index.js
const functions = require('firebase-functions');
const express =require("express");
const cors = require('cors')({origin: true});//เพื่อให้สามารถเรียกใช้งาน API ข้าม Domain ได้
const app=express();//สร้าง object express สำหรับ http request
const jwt = require('jsonwebtoken');//สร้าง object json web token สำหรับทำ Authentication
//สร้าง api function โดยตรวจสอบ token ก่อน
app.get("/api/authen/:token",(request, response) => { //:token คือ ค่าของ token ที่ส่งมา
//cors เพื่อให้เราสามารถเรียกใช้งานข้าม Domain ได้
cors(request, response, () => {
//ตรวจสอบ token
jwt.verify(request.params.token, 'secretkey', (err, authData) => {
if(err)//กรณี Toekn ไม่ถูกต้อง
{
response.sendStatus(403);
}
else
{
response.json({
message: 'API',
authData
});
}
});
});
});
//สร้าง api function สำหรับรับ token
app.get("/api/get_token",(request, response) => {
//cors เพื่อให้เราสามารถเรียกใช้งานข้าม Domain ได้
cors(request, response, () => {
//ตัวอย่าง user
const user = {
id: 1,
username: 'Job',
email: 'jobnuntawat@www.com'
}
jwt.sign({user}, 'secretkey',(err,token)=>{//สร้าง token ของ user
if(err)
{
response.send("Error !! ");
}
else
{
response.json({token}); //ส่ง token กลับไปให้ client
}
});
});
});
exports.app = functions.https.onRequest(app);
3. ทดลองรัน local โดยพิมพ์คำสั่ง firebase serve --only functions
4. ทดลองเปิด browser โดยเรียก function รับค่า token โดยเรียก /app/api/get_token โดยใน browser จะแสดง token มา
โดยหากเราเรียก /app/api/authen/ โดยไม่มี token ผลลัพธ์ที่ได้จะเป็น Forbidden
5. Deploy firebase function โดยพิพมพ์คำสั่ง npm install --save firebase-functions@lastest
จากนั้น พิมพ์ firebase deploy
6. ทดลองเรียก api จากภายนอก โดยพิมพ์ code
<script>
var xhttp = new XMLHttpRequest();
//รับค่า token
xhttp.open("GET","https://us-central1-mycloudfunction-788b6.cloudfunctions.net/app/api/get_token", true);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// เมื่อ server ส่งข้อมูลกลับมาแล้วเก็บค่า token ไว้ในตัวแปล token
let token_obj = JSON.parse(xhttp.responseText);
let token=token_obj.token;
//เรียก /app/api/authen โดย ส่ง token ที่ได้มาไปด้วย
xhttp.open("GET","https://us-central1-mycloudfunction-788b6.cloudfunctions.net/app/api/authen/"+token, true);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//เมื่อ server ส่งข้อมูลกลับมาแล้วให้แสดงข้อมูลตัวอย่าง user
document.write(xhttp.responseText);
}
};
xhttp.send();
}
};
xhttp.send();
</script>
โดยผลลัพธ์ที่ได้เมื่อรันจะได้เป็น json ที่แสดงข้อมูลตัวอย่าง user
{"message":"API","authData":{"user":{"id":1,"username":"Job","email":"jobnuntawat@www.com"},"iat":1536992705}}
โดยพิมพ์คำสั่ง npm install jsonwebtoken
2. แก้ code ไฟล์ index.js
const functions = require('firebase-functions');
const express =require("express");
const cors = require('cors')({origin: true});//เพื่อให้สามารถเรียกใช้งาน API ข้าม Domain ได้
const app=express();//สร้าง object express สำหรับ http request
const jwt = require('jsonwebtoken');//สร้าง object json web token สำหรับทำ Authentication
//สร้าง api function โดยตรวจสอบ token ก่อน
app.get("/api/authen/:token",(request, response) => { //:token คือ ค่าของ token ที่ส่งมา
//cors เพื่อให้เราสามารถเรียกใช้งานข้าม Domain ได้
cors(request, response, () => {
//ตรวจสอบ token
jwt.verify(request.params.token, 'secretkey', (err, authData) => {
if(err)//กรณี Toekn ไม่ถูกต้อง
{
response.sendStatus(403);
}
else
{
response.json({
message: 'API',
authData
});
}
});
});
});
//สร้าง api function สำหรับรับ token
app.get("/api/get_token",(request, response) => {
//cors เพื่อให้เราสามารถเรียกใช้งานข้าม Domain ได้
cors(request, response, () => {
//ตัวอย่าง user
const user = {
id: 1,
username: 'Job',
email: 'jobnuntawat@www.com'
}
jwt.sign({user}, 'secretkey',(err,token)=>{//สร้าง token ของ user
if(err)
{
response.send("Error !! ");
}
else
{
response.json({token}); //ส่ง token กลับไปให้ client
}
});
});
});
exports.app = functions.https.onRequest(app);
3. ทดลองรัน local โดยพิมพ์คำสั่ง firebase serve --only functions
4. ทดลองเปิด browser โดยเรียก function รับค่า token โดยเรียก /app/api/get_token โดยใน browser จะแสดง token มา
โดยหากเราเรียก /app/api/authen/ โดยไม่มี token ผลลัพธ์ที่ได้จะเป็น Forbidden
5. Deploy firebase function โดยพิพมพ์คำสั่ง npm install --save firebase-functions@lastest
จากนั้น พิมพ์ firebase deploy
6. ทดลองเรียก api จากภายนอก โดยพิมพ์ code
<script>
var xhttp = new XMLHttpRequest();
//รับค่า token
xhttp.open("GET","https://us-central1-mycloudfunction-788b6.cloudfunctions.net/app/api/get_token", true);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// เมื่อ server ส่งข้อมูลกลับมาแล้วเก็บค่า token ไว้ในตัวแปล token
let token_obj = JSON.parse(xhttp.responseText);
let token=token_obj.token;
//เรียก /app/api/authen โดย ส่ง token ที่ได้มาไปด้วย
xhttp.open("GET","https://us-central1-mycloudfunction-788b6.cloudfunctions.net/app/api/authen/"+token, true);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//เมื่อ server ส่งข้อมูลกลับมาแล้วให้แสดงข้อมูลตัวอย่าง user
document.write(xhttp.responseText);
}
};
xhttp.send();
}
};
xhttp.send();
</script>
โดยผลลัพธ์ที่ได้เมื่อรันจะได้เป็น json ที่แสดงข้อมูลตัวอย่าง user
{"message":"API","authData":{"user":{"id":1,"username":"Job","email":"jobnuntawat@www.com"},"iat":1536992705}}