หลังจากเขียน golang มาซักพักนึง ก็อยากมาแชร์ข้อมูลให้ทุกคนกัน :) โดยรอบนี้ จะเป็นบันทึกการทำ jwt ที่เคยทำ โดยอาศัยข้อมูลจาก
https://medium.com/wesionary-team/jwt-authentication-in-golang-with-gin-63dbc0816d55
ซึ่งผมอยากเอามาบันทึกเป็นภาษาไทย เพื่อช่วยให้ทุกคนเข้าถึง golang กันมากขึ้น ดังนั้น code ส่วนใหญ่จะเหมือนกับใน link ข้างต้นเลย
เอาหละ มาเริ่มกันเลยดีกว่า !!!
อันดับแรก สร้าง project โดยสร้างแบบ go module (สำหรับใครที่ยังไม่เคยใช้. แนะนำให้ลองทำดู เพราะในขั้นตอนการ build docker จะทำได้ง่ายมากขึ้น จัดการ package ต่างๆสบายขึ้นเยอะเลย) ลองไปดูในลิ้งนี้ก็ช่วยได้พอควรเลย shorturl.at/eIXZ7
อ่อ เมื่อเราใช้ go module เราไม่จำเป็นต้องสร้างโปรเจคใน GOPATH อีกต่อไป ดังนั้น จะสร้างไฟล์ที่ไหนก็ได้เลย
หลังจากสร้างโฟลเดอร์เปล่าแล้วก็สร้าง go mod ด้วย command ตามนี้เลย
$ go mod init github.com/{your_username}/{repo_name}ตัวอย่างคำสั่งของผม$ go mod init github.com/krittawatcode/go-jwt
ได้ project แล้ว ก็ go get สิ่งต่างๆที่ต้องใช้
go get -u github.com/gin-gonic/gingo get -u github.com/dgrijalva/jwt-go
จะสังเกตว่าจะมีไฟล์ใหม่ขึ้นมาสองไฟล์คือ go.mod และ go.sum ซึ่งทั้งสองไฟล์จะทำหน้าที่ไปดึง gin และ jwt-go แทนที่ปกติเราจะไปหาที่ GOPATH
เอาหละ เราก็มาถึงขั้นถัดไป project structure !! ก็จะวางโครงประมาณนี้เลย
ต่อมาเราจะเริ่มโดยเขียน service และ model ที่เกี่ยวข้องกัน
ไฟล์แรก JWTAuthentication.go
โดยใน JWTAuthentication.go จะมีสอง function หลักคือ GenerateToken และ ValidateToken โดยหลักการทำงานคือเขียน interface JWTService ขึ้นมา และสร้าง internal struct jwtService และมี 2 function ข้างต้นเพื่อ satisfy interface ข้างต้น
ต่อมา LoginService.go
วางโครงสร้างคล้ายกัน โดยมี interface LoginService และ struct loginInformation ที่ satisfy interface
ต่อมา สร้าง model สำหรับใช้ตอนรับข้อมูลขาเข้า
เมื่อ service พร้อม model พร้อม ถัดมาก็มาทำ controller
ก็จะวางคล้ายๆกันคือสร้าง interfact สร้าง struct ที่มี func มา satisfy interface
ต่อมา เมื่อมี controller ก็นำ controller ไปใช้งาน โดยเรียกผ่าน main.go (ตอนเอาไปวางตอนแรกอาจมี error noti ตรง middleware นะครับ แต่ไม่เป็นไร เราจะเขียนในขั้นถัดไป)
โดยใน main นั้นจะมี router โดยแยกออกเป็นสอง router หนึ่งสำหรับ path url ที่ไม่ต้องวิ่งผ่านการตรวจเชค jwt หรือก็คือ path /login และอีก router สำหรับ url ต้องตรวจเชค token ก่อน โดยเซทให้ใช้ middleware.AuthorizeJWT() ดักทุก request ที่เรียก path url ในกลุ่มนี้
ใน main จะ มีการสร้าง var loginService, jwtService, loginController เพื่อทำการ mockup ค่าสำหรับ validate token ซึ่งในการทำงานจริง code ชุดนี้ไปใช้ ก็ตัดส่วน StaticLoginService() ใน LoginService.go ไปได้เลย และในการ validate user ด้วย function LoginUser() ใน LoginService ก็ไป custom เอาเอง อาจไป validate ldap หรือ db แล้วค่อย return true ออกไปก็ตามสะดวกเลยจ้า
หลังจากนั้น ก็ทำตัว middleware เพื่อตรวจ token ก่อนเข้า path
อะเมื่อทุกอย่างพร้อม ก็ลองรันกันเลย
go run main.go
เมื่อลองรันแล้ว ก็ลองยิง request ด้วย postman ดู
POST: http://localhost:8080/login ด้วย body ดังรูป ก็จะได้ response ประมาณในรูป
ต่อมา ลองยิง GET: http://localhost:8080/v1/test
ก็จะได้ response Status 401 Unauthorized กลับมา ทีนี้ เอา token ที่ได้มาจากตอน login มาใส่ใน Header set header
Authorization : Bearer {{token}}
แล้วยิงใหม่ ก็จะได้แบบนี้
โดยรวมๆก็มีประมาณนี้แหละครับ
สำหรับใครที่จะนำไปใช้งานเลย ก็ clone https://github.com/krittawatcode/go-jwt ไปใช้ได้เลยครับ (ปล. repoในของต้นฉบับข้างต้นของบทความจะมี bug อยู่นิดหน่อยนะครับ)
ไว้เจอกันใหม่นะครับ
รอบหน้าจะเอาการใช้งาน gorm connect sql และ demo การทำ api สำหรับ search มาให้ดูกัน
ไว้เจอกันใหม่ครับ ;)