การ ทำ passport: คุณกำลังดูกระทู้
สอนทำเว็บไซต์ด้วย Node.js, Express และ MongoDB ตอนที่ 9 – ทำระบบ Login ด้วย Passport.js
In
สวัสดีครับ มาต่อกันที่ตอนที่ 9 กันนะครับ สำหรับตอนนี้เราจะมาเริ่มทำส่วนการ Login ด้วยการใช้ Middleware และการใช้ตัวข่วยอย่าง Passport.js กันนะครับ
โดยตัวอย่างนี้ จะเป็นกึ่งๆ Workshop นิดๆ จากเนื้อหา ตอนที่ 1-8 มารวมเป็นบทความนี้ครับ (อาจจะไปเร็วนึงนึง เพราะ assume ว่าผู้อ่าน ได้อ่าน และทำความเข้าใจเนื้อหาตอนก่อนๆมาแล้วนะครับ)
- ใช้ Express Generator ในสร้างโปรเจ็ค
- ใช้ Pug ในการทำ Template มีหน้า Login / Register และหน้า Home เพื่อแสดงข้อมูลถ้า Login เรียบร้อยแล้ว
- เก็บข้อมูล User ไว้ใน MongoDB
- ใช้งาน Passport.js (Middleware ที่ช่วยในการทำ Authentication)
- มีการเก็บข้อมูล Session (จะได้เรียนรู้ในบทความนี้)
โดยในตัวอย่างนี้ จะเป็น Web Application แบบทั่วๆไปนะครับ คือเป็น Server Side Rendering ไม่ใช่เป็น Single Page Application นะครับ
ตัวอย่างเว็บ หลังจากทำเว็บ จะได้หน้าตาประมาณนี้นะครับ http://example-web.now.sh
ส่วนเรื่อง Single Page Application (SPA) และการทำ RESTful API สำหรับส่วน Backend เดี๋ยวจะพูดถึงในบทถัดๆไปครับ
เนื้อหาบทเรียน
Step 1 – Create Project
เริ่มต้นเราไม่รอช้า ทำการสร้างโปรเจ็คใหม่ด้วย Express Generator เลยครับ
npx express-generator --view
=
pug ahoy-node-passport
เราก็จะได้โปรเจ็ค Express ขึ้นมา โดยมี Pug เป็น Template ครับ (สำหรับตัวอย่างนี้ผมจะพยายามข้ามเรื่อง Style ของเว็บนะครับ ไม่ได้เน้นความสวยงาม เน้น Functionality ที่มันทำงานได้) โดยตัว UI ผมใช้เป็น Bootstrap ธรรมดาเลยนะครับ
ต่อมาที่ไฟล์ views/layout.pug
ผมเพิ่ม Bootstrap css ลงไปครับ
doctype html
html
head
meta(name='viewport', content='width=device-width, initial-scale=1')
title= title
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css', integrity='sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm', crossorigin='anonymous')
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
ทำการสั่ง Start server
npm
start
จะได้ Server รันบน Localhost ครับ http://localhost:3000
Step 2 – สร้างหน้า Login / Register
ต่อมาเราจะทำหน้า Form สำหรับ Login และ Register ครับ เป็นแบบง่ายๆ เลยคือ HTML มี input สำหรับใส่ username และ password ครับ โดย Register จะมี Optional ให้ใส่ name ตอนลงทะเบียนเพิ่มไปด้วย
สร้างไฟล์ views/register.pug
ขึ้นมา
extend layout
block content
.form-container
form(class="form-signin" method="POST" action="/auth/register")
h2 Please Register
.form-group
label( for="name" class="sr-only") Name (Optional)
input(type="text" name="name" id="name" class="form-control" placeholder="Name")
.form-group
label( for="username" class="sr-only") Username
input(type="text" name="username" id="username" class="form-control" placeholder="Username" required)
.form-group
label(for="password" class="sr-only") Password
input(type="password" name="password" id="password" class="form-control" placeholder="Password" required)
button(class="btn btn-primary btn-block" type="submit") Register
a(href="/login", class="btn btn-link") Have an account?
โดยเมื่อ Submit form มันจะไปเรียก POST /auth/register
นะครับ
ต่อมาสร้าง views/login.pug
เหมือนกัน คล้ายๆกับ Register เลย เพียงแค่ลบ input name ออก และเปลี่ยน method เป็น POST /auth/login
ครับ
extend layout
block content
.form-container
form(class="form-signin" method="POST" action="/auth/login")
h2 Please Login
.form-group
label( for="username" class="sr-only") Username
input(type="text" name="username" id="username" class="form-control" placeholder="Username" required)
.form-group
label(for="password" class="sr-only") Password
input(type="password" name="password" id="password" class="form-control" placeholder="Password" required)
button(class="btn btn-primary btn-block" type="submit") Login
a(href="/register", class="btn btn-link") Don't have an account?
ต่อมาใส่ CSS นิดนึง ตรงไฟล์ public/stylesheets/style.css
.form-container
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
height
:
100
vh
;
}
.form-signin
{
width
:
100
%
;
max-width
:
420
px
;
padding
:
2
rem
;
margin
:
auto
;
background-color
:
#f3f3f3
;
}
ทีนี้เราจะเพิ่ม Router ของ Express กันครับ ตัว Generator มันสร้างไว้ให้แล้ว ทีนี้ผมก็จะทำจากไฟล์เดิมเลยคือ routes/index.js
const
express
=
require
(
'express'
)
const
router
=
express
.
Router
(
)
router
.
get
(
'/'
,
function
(
req
,
res
,
next
)
{
res
.
render
(
'index'
,
{
title
:
'Express'
}
)
}
)
router
.
get
(
'/register'
,
(
req
,
res
)
=>
{
res
.
render
(
'register'
)
}
)
router
.
get
(
'/login'
,
(
req
,
res
)
=>
{
res
.
render
(
'login'
)
}
)
module
.
exports
=
router
ไฟล์ index
นี้ คือ เพิ่ม /register
และ /login
ให้มัน render ไฟล์ pug template ที่เราเพิ่งสร้างด้านบนครับ
ทีนี้ลองเข้าเว็บ http://localhost:3000/register และ http://localhost:3000/login เราก็จะได้หน้า Form สำหรับ Login และ Register แล้วครับ
Step 3 – รับข้อมูลจาก Form
ต่อมาเราจะทำการรับข้อมูลจาก Form ที่กรอกเข้ามาจากหน้า Login และ Register นะครับ โดยใช้ routes ที่ตัว Express Generator นั้น gen มาให้แล้ว คือ routes/users.js
แต่ผมจะเปลี่ยนชื่อใหม่เป็น routes/auth.js
ละกันครับ
const
express
=
require
(
'express'
)
const
router
=
express
.
Router
(
)
router
.
post
(
'/register'
,
(
req
,
res
)
=>
{
console
.
log
(
req
.
body
)
res
.
redirect
(
'/'
)
}
)
router
.
post
(
'/login'
,
(
req
,
res
)
=>
{
console
.
log
(
req
.
body
)
res
.
redirect
(
'/'
)
}
)
module
.
exports
=
router
โดย กำหนดเป็นแบบ .post()
ครับ เพื่อรับค่าจาก Form ทีนี้ เราลอง console.log ดูค่า req.body
ดูครับ
แก้ไข app.js
นิดหน่อย เนื่องจากผมเปลี่ยนชื่อไฟล์ บรรทัด 6-7
var
indexRouter
=
require
(
'./routes/index'
)
var
authRouter
=
require
(
'./routes/auth'
)
และบรรทัด 22 23
app
.
use
(
'/'
,
indexRouter
)
app
.
use
(
'/auth'
,
authRouter
)
ทีนี้เวลาเรา Submit จะตอน Login หรือ Register ค่าก็จะถูกส่งมา เข้า route router.post('/register')
เราก็จะเห็นค่า req.body
ครับ ทีนี้ส่ิงที่เราจะต้องทำคือ save ค่าที่ user ส่งมา เนี่ย ลง database
จริงๆแล้ว การใช้งาน Production เราต้องมีการ validate ค่าต่างๆ ด้วยนะครับ เช่น express-validation, joi, yup เป็นต้น
Step 4 – เชื่อมต่อ MongoDB
ต่อมาเราจะทำการเชื่อมต่อ MongoDB โดยใช้ Mongoose ครับ เพื่อเก็บข้อมูล username / password ในระบบ นั่นเอง
ติดตั้ง Mongoose
npm install mongoose
ต่อมาสร้างไฟล์ db.js
เพื่อไว้ connect mongodb
const
mongoose
=
require
(
'mongoose'
)
mongoose
.
connect
(
'mongodb://localhost:27017/ahoy-node-passport'
,
{
useNewUrlParser
:
true
,
useUnifiedTopology
:
true
}
)
ชื่อ Database แล้วแต่เพื่อนๆ จะตั้งเลยนะครับ ใครจะเป็นอะไรก็ได้ ไม่จำเป็นต้อง
ahoy-node-passport
เหมือนในบทความ
ต่อมาเพิ่มตรงนี้ลงไปในไฟล์ app.js
เพื่อ import ไฟล์ที่เรา connect mongodb ไว้
require
(
'./db'
)
ต่อมา สร้าง User Model ขึ้นมาที่ไฟล์ models/User.js
เพื่อเอาไว้ใช้ตอน insert หรือ query
const
mongoose
=
require
(
'mongoose'
)
const
Schema
=
mongoose
.
Schema
const
userSchema
=
new
Schema
(
{
name
:
String
,
username
:
{
type
:
String
,
unique
:
true
}
,
password
:
String
}
)
const
UserModel
=
mongoose
.
model
(
'User'
,
userSchema
)
module
.
exports
=
UserModel
ทีนี้กลับไปที่ routes/auth.js
ตอน login และ register เราก็รับค่า req.body
มา แล้ว save ลง database เลยครับ
const
express
=
require
(
'express'
)
const
router
=
express
.
Router
(
)
const
User
=
require
(
'../models/User'
)
router
.
post
(
'/register'
,
async
(
req
,
res
)
=>
{
const
user
=
new
User
(
req
.
body
)
await
user
.
save
(
)
res
.
render
(
'index'
,
{
user
}
)
}
)
router
.
post
(
'/login'
,
async
(
req
,
res
)
=>
{
const
{
username
,
password
}
=
req
.
body
const
user
=
await
User
.
findOne
(
{
username
,
password
}
)
if
(
user
)
{
return
res
.
render
(
'index'
,
{
user
}
)
}
else
{
return
res
.
render
(
'login'
,
{
message
:
'Email or Password incorrect'
}
)
}
}
)
module
.
exports
=
router
โดยสำหรับ Register เราก็จะรับ req.body
มาเซฟลง Database และ Login เราก็จะรับ input มาเป้น criteria ในการ findOne()
หา User ในระบบ ถ้าเจอ และ username และ password ถูก ก็แสดงว่า user login เข้าสู่ระบบได้สำเร็จ
แต่ๆ ระบบเรายังมีช่องโหว่ และมีสิ่งที่ไม่ควรทำอย่างยิ่ง!! แม้ว่าจะเป็นแค่ Development หรือทำระบบเล็กๆ หรือทำอะไรขึ้นมาเล่นๆ นั่นก็คือ Password ไม่ควรเก็บเป็น Plain Text
Step 4 – Hash Password ซะ
ข้อนี้เป็นสิ่งที่จำเป็นที่สุด !!! เน้นย้ำเลยครับ Password ที่เราเก็บในระบบ ห้ามเก็บแบบ Plain Text เด็ดขาด เราจะไม่สามารถรู้ได้เลยว่า Password ที่เก็บคืออะไร ไม่สามารถเปลี่ยน Password ให้คนอื่นได้ ทำได้อย่างเดียว คือการ Reset Password ครับ
และถ้าเราไปใช้ระบบ หรือบริการไหน ที่เราทำการขอ Forgot Password แล้วระบบส่ง Password เรากลับมาในอีเมล์ นั้นแสดงว่าระบบหรือบริการนั้นเก็บ Password เราแบบ Plain text สามารถเห็น Password เราและของคนอื่นๆในระบบได้หมดเลย เรียกได้ว่าไม่ปลอดภัยมากๆ และควรเปลี่ยน Password โดยด่วน (ไม่ว่าจะเป็น Developers, Admin หรือใครก็ตาม ก็ไม่มีสิทธิ์ หรือไม่ควรจะรู้ Password คนอื่นได้ครับ)
ส่วนการ Hash นั้น คือการเอา Password ปกติมาเข้ารหัสทงเดียว โดยได้ผลลัพธ์ที่เราไม่สามารถรู้ได้ว่า Password เราคืออะไร ส่วนความปลอดภัย ขึ้นอยู่กับ Algorithm และจำนวนการ hash ครับ
เราก็ไม่สามารถรู้ได้ว่า Password คืออะไร วิธีการที่ใช้ในการเช็คว่า Password ถูกต้องมั้ย คือการเปรียบเทียบ สิ่งที่ Input มากับค่า Password ที่มันถูก hash แล้ว ถ้ามันตรงกัน แสดงว่า Password ถูกครับ
การ Hash เราจะใช้ Library ที่ชื่อว่า bcrypt
ครับ ทำการติดตั้งลงไป
npm
install
bcrypt
ทีนี้การ Hash Password เราจะทำได้โดยการเรียก function
const
saltRounds
=
10
bcrypt
.
hash
(
'mypassword'
,
saltRounds
,
function
(
err
,
hash
)
{
}
)
ส่วนการ Compare ก็จะใช้แบบนี้
bcrypt
.
compare
(
'mypassword'
,
hash
,
function
(
err
,
result
)
{
}
)
ซึ่งทั้งคู่ เป็นแบบ callback base เราสามารถใช้ hashSync
และ compareSync
เพื่อให้มัน hash/compare แบบ synchronus ได้เช่นกันครับ
const
hash
=
bcrypt
.
hashSync
(
myPlaintextPassword
,
salt
)
const
result
=
bcrypt
.
compareSync
(
myPlaintextPassword
,
hash
)
ทีนี้กลับมาที่ส่วนรับค่า req.body
จาก User ตอนสมัครและลงทะเบียน เราต้องทำการ hash ค่า password ของ User ก่อน แบบนี้ครับ routes/auth.js
const
express
=
require
(
'express'
)
const
bcrypt
=
require
(
'bcrypt'
)
const
router
=
express
.
Router
(
)
const
User
=
require
(
'../models/User'
)
router
.
post
(
'/register'
,
async
(
req
,
res
)
=>
{
const
{
username
,
password
,
name
}
=
req
.
body
if
(
!
name
||
!
username
||
!
password
)
{
return
res
.
render
(
'register'
,
{
message
:
'Please try again'
}
)
}
const
passwordHash
=
bcrypt
.
hashSync
(
password
,
10
)
const
user
=
new
User
(
{
name
,
username
,
password
:
passwordHash
}
)
await
user
.
save
(
)
res
.
render
(
'index'
,
{
user
}
)
}
)
ส่วนของ Login ก็ทำแบบเดียวกันครับ เราจะ findOne()
โดยใช้ Username เราจะได้ค่า password
ที่ hash แล้วใน Database จากนั้นค่อยเอาค่าที่ hash ที่เราเก็บไว้ มาเปรียบเทียบกับที่ User ส่งมาจาก form login
const
express
=
require
(
'express'
)
const
bcrypt
=
require
(
'bcrypt'
)
const
router
=
express
.
Router
(
)
const
User
=
require
(
'../models/User'
)
router
.
post
(
'/login'
,
async
(
req
,
res
)
=>
{
const
{
username
,
password
}
=
req
.
body
if
(
!
username
||
!
password
)
{
return
res
.
render
(
'register'
,
{
message
:
'Please try again'
}
)
}
const
user
=
await
User
.
findOne
(
{
username
}
)
if
(
user
)
{
const
isCorrect
=
bcrypt
.
compareSync
(
password
,
user
.
password
)
if
(
isCorrect
)
{
return
res
.
render
(
'index'
,
{
user
}
)
}
else
{
return
res
.
render
(
'login'
,
{
message
:
'Username or Password incorrect'
}
)
}
}
else
{
return
res
.
render
(
'login'
,
{
message
:
'Username does not exist.'
}
)
}
}
)
module
.
exports
=
router
ทีนี้ ข้อมูลที่เราเก็บส่วนที่เป็น Password ก็จะถูก Hash เรียบร้อยแล้ว ลองทำการ Register และ Login ใหม่ รวมถึงลองเช็คใน Mongo Database ดูครับ ว่าข้อมูลเราจะไม่ใช่ Plain Text แล้ว
Step 5 – เก็บ Session เมื่อ Login
ต่อมา กรณีที่เรา Login หรือ Register จะทำยังไงให้ระบบรู้ว่าเรายังอยู่ในระบบ ยังไม่ได้ Logout ไปไหน ทุกครั้งที่ Refresh หรือ ปิดแท้ป แล้วเปิดใหม่ ไม่จำเป็นต้อง Login แต่ต้องสามารถเข้าได้เลย เพราะว่ามี Session อยู่
วิธีที่ง่ายที่สุดคือ ทำ Middleware ขึ้นมาใช้เองครับ
อย่างที่รู้จากบทความตอนก่อนว่า Middleware คือ function ของ Express ที่มี request ,response และ next เราสามารถ implement อะไรก็ได้ ตามที่เราต้องการ
const
isLoggedIn
=
(
req
,
res
,
next
)
=>
{
if
(
!
req
.
user
)
{
res
.
redirect
(
'/login'
)
}
next
(
)
}
เราเพียงแค่สร้าง Function ขึ้นมาครับ เป็น Middleware ที่เอาไว้เช็คว่ามี req.user
มั้ย? ถ้ามีแสดงว่า User นั้น Login หรือมี Session อยู่
ต่อมา ก็แค่เอาไปใส่ใน routes/index.js
แบบนี้
router
.
get
(
'/'
,
isLoggedIn
,
function
(
req
,
res
,
next
)
{
res
.
render
(
'index'
,
{
title
:
'Express'
}
)
}
)
ทีนี้ พอเข้าหน้า http://localhost:3000 จะถูกเด้งไปหน้า /login
ทุกครั้ง เนื่องจากไม่มี req.user
ต่อมา เราเพิ่ม req.user
ตอนที่เค้า Login เรียบร้อยแล้ว หรือ Register เรียบร้อยแล้ว ที่ไฟล์ routes/auth.js
router
.
post
(
'/login'
,
async
(
req
,
res
)
=>
{
...
if
(
isCorrect
)
{
req
.
user
=
user
;
return
res
.
render
(
'index'
,
{
user
}
)
;
}
}
assign ค่า user จาก database ไปใส่ object req
ก่อนที่จะ render index ครับ ทีนี้เวลาเรา ยังไม่ได้ login มันก็จะเด้งไปหน้า login แต่ถ้า login เรียบร้อยแล้ว มันจะ redirect ไป index แล้วก็ไม่ถูก redirect มา login แล้ว เพราะเรามี req.user
ครับ
ทีนี้ปัญหาก็ยังมีคือ เรา refresh มันไม่ได้จำ req.user
ครับ
วิธีแก้ไขคือ ต้องพึ่ง Session ครับ วิธีง่ายๆ คือใช้ express-session
ทำการติดตั้ง
npm
install
express-session
จากนั้นที่ไฟล์ app.js
เพิ่มนี้ลงไป
const
session
=
require
(
'express-session'
)
app
.
use
(
cookieParser
(
)
)
app
.
use
(
session
(
{
secret
:
'my_super_secret'
,
resave
:
false
,
saveUninitialized
:
false
}
)
)
ตัว Middleware ของ Session จะสร้าง req.session
ขึ้นมาครับ ทีนี้เราก็สามารถ assign ค่าไปที่ object นี้ได้
ทีนี้ส่วนที่ Login และ Register ที่ใช้ req.user
ก็เปลี่ยนเป็น
req
.
session
.
user
=
user
แล้วส่วน isLoggedIn
ก็เปลี่ยนเป็นแบบนี้
const
isLoggedIn
=
(
req
,
res
,
next
)
=>
{
if
(
!
req
.
session
.
user
)
{
return
res
.
redirect
(
'/login'
)
}
next
(
)
}
ทีนี้เราก็จะได้ Session แล้วครับ ที่เป็น built-in และมันจะ clear ก็ต่อเมื่อเรา restart server ครับ
Step 6 – ใช้ Passport.js มาช่วยในการ Authentication
ต่อมา เราไม่อยากเขียน Middleware และ Session เอง เราสามารถใช้ Passport.js ซึ่งเป็น Library ที่นิยมมาทำ Authentication ตัวนึงของ Node.js เลยครับ ด้วยความที่เค้า Provide function และพวก Helper ต่างๆ
มาให้ ทำให้มันค่อนข้างง่ายครับ
ซึ่งจริงๆแล้ว Passport.js สามารถทำ Authentication ผ่าน Social Network อื่นๆ เช่น Twitter, Facebook, Google, Github ได้หมดเลยครับ แต่สำหรับบทความนี้ ขอเป็นตัวอย่างเฉพาะ Username / Password ละกันเนาะ
และใน Passport.js เราจะเรียกมันว่า Strategy ครับ โดยใช้ passport-local ครับ
ทำการติดตั้ง
npm
install
passport passport-local
ที่ไฟล์ app.js
เพิ่มนี้ลงไป ค่อนข้างเยอะนิดนึง เดี๋ยวจะพยายามอธิบายครับ
const
passport
=
require
(
'passport'
)
const
LocalStrategy
=
require
(
'passport-local'
)
.
Strategy
passport
.
use
(
new
LocalStrategy
(
(
username
,
password
,
cb
)
=>
{
User
.
findOne
(
{
username
}
,
(
err
,
user
)
=>
{
if
(
err
)
{
return
cb
(
err
)
}
if
(
!
user
)
{
return
cb
(
null
,
false
)
}
if
(
bcrypt
.
compareSync
(
password
,
user
.
password
)
)
{
return
cb
(
null
,
user
)
}
return
cb
(
null
,
false
)
}
)
}
)
)
passport
.
serializeUser
(
(
user
,
cb
)
=>
{
cb
(
null
,
user
.
_id_
)
}
)
passport
.
deserializeUser
(
(
id
,
cb
)
=>
{
User
.
findById
(
id
,
(
err
,
user
)
=>
{
if
(
err
)
{
return
cb
(
err
)
}
cb
(
null
,
user
)
}
)
}
)
app
.
use
(
passport
.
initialize
(
)
)
app
.
use
(
passport
.
session
(
)
)
ส่วนต่อมาคือ ไฟล์ routes/auth.js
จะใช้ Passport มาเป็น Middleware ดัง syntax แบบนี้
router
.
post
(
'/login'
,
middleware
,
handlers
)
ก็จะได้เป็น
router
.
post
(
'/login'
,
passport
.
authenticate
(
'local'
,
{
failureRedirect
:
'/login'
,
successRedirect
:
'/'
}
)
,
async
(
req
,
res
)
=>
{
const
{
username
,
password
}
=
req
.
body
return
res
.
redirect
(
'/'
)
}
)
แถม Logic ที่เรา implement ก็ไม่ต้องใช้แล้ว เพราะมัน handle ที่ Passport LocalStrategy ที่ไฟล์ app.js
เรียบร้อยครับ
สุดท้าย ฟังค์ชั่น isLoggedIn
ที่เราใช้ตอน session เราก็เปลี่ยนมา handle req.isAuthenticated()
ซึ่งเป็น helper ของ Passport กรณีที่มี session มันก็จะ return true ได้แบบนี้ ไฟล์ routes/index.js
const
isLoggedIn
=
(
req
,
res
,
next
)
=>
{
if
(
req
.
isAuthenticated
(
)
)
{
next
(
)
}
else
{
res
.
redirect
(
'/login'
)
}
}
สุดท้าย ท้ายสุด ลืมส่วน Logout ครับ เรามีปุ่ม Logout และ request มาที่ /logout
เราก็เพิ่ม router ส่วนนี้เลย ที่ไฟล์ routes/index.js
router
.
get
(
'/logout'
,
(
req
,
res
)
=>
{
req
.
logout
(
)
res
.
redirect
(
'/'
)
}
)
ตัว Passport มี req.logout()
ที่จัดการพวก session และ logout ให้เรา จากนั้นก็ redirect กลับไป /
เป็นอันเรียบร้อยครบ flow การทำงาน
สรุป
ก็บทความนี้ เป็น Flow การทำ Authentication ตั้งแต่เริ่มต้น ใช้แบบธรรมดา จนมี Session ทำ Middleware เอง และสุดท้ายใช้ Library อย่าง Passport.js เข้ามาช่วย ทำให้ประหยัดเวลา ของเราไปได้มากทีเดียว
ก็หวังว่าบทความนี้เพื่อนๆ จะได้ไอเดียนำไปต่อยอด ได้รู้ว่า Session มันทำงานยังไง ได้รู้ว่า Passport มันทำงานยังไง Serialize / Deserialize เอาอะไรไปเก็บใน Session พวกนี้
และตัวอย่าง มันก็ไม่ได้สมบูรณ์นะครับ อาจจะมีบ้าง ที่ไม่ครบ เป้าหมายของบทความนี้คือเน้นให้เห็นไอเดีย การใช้งานครับ หากขาดตกบกพร่องตรงไหนไป ขออภัยด้วยครับ และหากใครติดปัญหา หรือไม่เข้าใจตรงไหน สามารถสอบถามได้ครับ หรือหากใครเจอข้อผิดพลาด สามารถแนะนำได้เช่นกันครับ
—
ส่วน Source Code (อยู่ part9) สามารถเข้าไปดาวน์โหลด หรือ clone ผ่าน Github ได้เลย หากใครไม่รู้จัก Git สามารถอ่านบทความนี้เพิ่มได้ครับ Git คืออะไร ? + พร้อมสอนใช้งาน Git และ Github
ขอบคุณครับ
❤️ Happy Coding
[NEW] พาสปอร์ตหมดอายุ ต่อพาสปอร์ตที่ไหน ใช้อะไรบ้าง 2563 | การ ทำ passport – Sonduongpaper
What is your feedback about?
Required
Please tell us how we can improve
Required
E-mail address – optional
Optional, only if you want us to follow up with you.
รีวิว | ทำ Passport ยุคนี้ 20 นาทีเสร็จ จริงหรอ???!!!
หลังจากที่ไม่ได้อัพคลิปมานาน กำลังจะมีภารกิจเดินทางไปต่างประเทศ ลองเช็คพาสปอร์ตดู อ้าววว อีก 6 เดือนหมดอายุ!!! โอเค ทำใหม่ก็ได้ เสิร์ชข้อมูลไปเจอ ทำ 20 นาทีเสร็จ อีก 2 วันรอรับได้เลย ช้าอยู่ใย ไปกรมการกงสุลสำนักงานใหญ่ที่แจ้งวัฒนะ ทำเรื่องเลยจ้า
จองคิวทำพาสปอร์ต >>> https://www.passport.in.th/
คลิปนี้ของดีเลยโปรโมทให้ เขาไม่ได้จ่ายนะจ๊ะ คริคริ
♦ CAMERA: Samsung Galaxy S7
♦ EDITING PROGRAM: Movie Maker
♦ MUSIC: Allie X Paper Love
Joakim Karud dizzy
♦ LOCATION: กรมการกงสุล กระทรวงต่างประเทศ
นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูเพิ่มเติม
บริการต่อใบอนุญาตทำงาน วีซ่า หมดอายุ 30 กันยายน 2564
📌 ให้ยื่นต่อใบอนุญาตทำงานก่อนหมดอายุ
👉 กลุ่มใบอนุญาตทำงาน วีซ่า หมดอายุ 30 กันยายน 2564
บริษัทฯเปิดรับให้บริการแล้ว ยื่นเอกสารได้ทันที วันนี้
โทร 028215965
นนทบุรี (สี่แยกแคราย) กด1
https://lin.ee/6JMHpxg
รัชดาซอย22 (MRT รัชดา) กด2
https://lin.ee/s7oT5Hj
สมุทรปราการ บางพลี (รพ.บางนา2) กด3
https://lin.ee/5ieFkR4
อัพเดท!! การทำพาสปอร์ตช่วงโควิด ปี2021 |Fernny’s diaryy 🌹
ฮัลโหลลลลลลทุกคน ช่วงที่ผ่านมามีโอกาสได้ไปเปลี่ยนพาสปอร์ตเล่มใหม่ เลยอยากอัพเดทให้ทุกคนดูว่าเป็นยังไงบ้าง ฝากกดไลค์ กด Subscribe ด้วยน้าาาาา❤🙏
ช่องทางการติดตาม:
https://www.instagram.com/fernnysiri/
https://www.facebook.com/Fernnysdiaryy107825317813560/
อัพเดทโควิด พาสปอร์ต2021 การทำพาสปอร์ต
12 เรื่องน่ารู้เกี่ยวกับการทำพาสปอร์ต!!!ทำที่ไหน ใช้เอกสารอะไร และข้อมูลทุกอย่างโดยละเอียดที่นี้
12 เรื่องน่ารู้เกี่ยวกับการทำพาสปอร์ต
การทำพาสปอร์ตรถ เพื่อไปขับเที่ยวที่ประเทศเพื่อนบ้านเรา
พาสปอร์ตรถหรือ หนังสืออนุญาตรถระหว่างประเทศ
นอกจากการดูบทความนี้แล้ว คุณยังสามารถดูข้อมูลที่เป็นประโยชน์อื่นๆ อีกมากมายที่เราให้ไว้ที่นี่: ดูบทความเพิ่มเติมในหมวดหมู่Wiki
ขอบคุณที่รับชมกระทู้ครับ การ ทำ passport