จัดการ HTTP Session ด้วย Spring Session + Redis

Phayao Boonon
4 min readDec 29, 2018

--

Session เป็นอีกเรื่งที่ Spring Framework รองรับด้วย Spring Session ที่สามารถจัดการกับ HTTP Session ได้ และมี data store ให้เลือกใช้ ตัวอย่างเช่น Redis, JDBC หรือ Hazelcast ซึ่งในบทความนี้ก็จะมาลองใช้งาน Spring Session อย่างง่ายซึ่งเก็บข้อมูลไว้บน Redis จัดการกับ Session ของ User Authentication 👨🏻‍💻

HTTP Session?

เป็นลำดับของ network request-response transaction ซึ่ง HTTP Client จะเริ่มการร้องขอ (Request) ด้วยการสร้าง TCP (Transmission Control Protocol) เชื่อมต่อกับ Port เฉพาะบน Server (โดยทั่วไปจะเป็น Port 80 แต่บางทีก็ใช้ Port 8080) ซึ่ง HTTP Server จะตรวจสอบบน Port นั้นสำหรับรอข้อความร้องขอของ Client เมื่อรับข้อความร้องแล้วขอ Server จะส่งสถานะกลับไป เช่น “HTTP/1.1 200 OK” พร้อมด้วยข้อความ

https://www.hackingarticles.in/beginner-guide-understand-cookies-session-management/

Spring Session

เป็น API และ implementation สำหรับจัดการกับ Session information ของผู้ใช้งาน (User) รองรับ clustered session โดยไม่ต้องอาศัย application container เฉพาะ โดยสามารถเชื่อมต่อกับ

  • HttpSession — แทนที่ HttpSession ใน application container (เช่น Tomcat) อีกทั้งยังรองรับ session ID ใน header เพื่อทำงานกับ RESTful API
  • WebSocket — สำหรับรักษา HttpSession ในการรับข้อความใน WebSocket
  • WebSession — แทนที่ WebSession ของ WebFlux ใน application container

ในบทความนี้จะใช้ Spring Session ในการจัดการกับ HttpSession โดยใช้ module Spring Session Data Redis ซึ่งเป็นการใช้ Redis สำหรับเก็บข้อมูลของ Session ในฝั่ง Server สำหรับจัดการกับ User Authentication ด้วย Basic Auth

แต่ Spring Session รองรับการเก็บข้อมูลในรูปแบบ RDMS ด้วย JDBC และ Hazalcase อีกด้วย

Create Spring Boot project

ด้วย Spring Initializr ด้วยการเลื่อก dependencies เป็น Web, Security, Session และ Redis

แล้วใช้ IntelliJ หรือ IDE อื่นเปิด Spring Boot project จะเห็นได้ว่าในส่วนของ Dependencies ของ pom.xml จะมี dependency spring-session-data-redis สำหรับใช้ Redis กับ HttpSession

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
....</dependencies>

เพิ่ม application configuration ให้กับ project สำหรับเชื่อมต่อกับ Redis ด้วย Spring Data ซึ่งเป็นการกำหนด Redis host และ port

spring-redis.host=localhost
spring-redis.port
=6379

Spring Session Configuration

สร้าง configuration สำหรับ Spring Session และ Redis ด้วยการใช้ annotation @EnableRedisHttpSession และ AbstractHttpSessionApplicationInitializer เป็นการ config สำหรับ Spring Boot auto configuration

Spring Security Configuration

สร้าง configuration สำหรับ Spring Security เพื่อใช้งาน Basic Auth ด้วย user ที่เป็น role ADMIN และ user admin และ password password โดยที่อนุญาติให้ role ที่เป็น ADMIN เท่านั้นที่ใช้งานได้ และใช้ authentication สำหรับ path /

Rest Controller

และสุดท้ายสร้าง RestController แบบง่ายๆ เพื่อให้ user สามารถใช้งาน RESTful API ได้ และตอบกลับเป็น “Hello Admin” ถ้า user ผ่าน authentication

Run Redis

เริ่มต้นการทำงานของ Redis server ด้วยคำสั่ง redis-server

Run Spring Boot App

เริ่มต้นการทำงานของ Spring Boot application ด้วยคำสั่ง mvn spring-boot:run

Test Application

เรามาทดสอบการทำงานของ Spring Session ด้วย Postman โดยที่เริ่มแรก request ไปที่ Spring Boot Application ด้วย No Auth (ไม่มี User credential) ก็จะได้ status code เป็น 401 Unauthorized นั้นก็หมายความว่า Application ต้องการ User credential เพื่อ Authentication

เมื่อเรา request อีกครั้งด้วย ฺBasic Auth (มี User credential— username: admin, password: password) จะได้ status code เป็น 200 OK ซึ่งก็หมายความว่าสามารถ Authenticated ด้วย Basic Auth ได้

ถ้าเรา request อีกครั้งด้วย No Auth (ไม่มี User credential) เราก็จะได้ 200 OK อยู่ นั้นหมายความว่า HTTP Session ของ Authentication ครั้งที่แล้วยังอยู่

ตรวจสอบ Session บน Redis ด้วย Redis-CLI โดยใช้คำสั่ง KEYS * เพื่อดูว่ามี key ของ Session อยู่ใน Redis หรือไม่ จะเห็นได้ว่ามี key session อยู่

ลบ Session ทั้งหมดด้วยคำสั่ง FLUSHALL และใช้คำสั่ง KEYS * อีกครั้งเพื่อดูว่ายังมี key session อยู่ไหม จะเห็นได้ว่าไม่มีอยู่แล้ว

เมื่อเรา request แบบ No Auth อีกครั้งจากที่ได้เมื่อสักครู่ก็จะเห็นว่าตอนนี้ได้ status code เป็น 401 Unauthorized ซึ่งก็คือไม่มี session บน Application แล้วเมื่อ request ไปอีกครั้งก็จะไม่อนุญาติให้ใช้งาน Application

สรุป

จากบทความนี้ใช้ Spring Session สำหรับจัดการกับ HTTP Session และเก็บข้อมูลเป็น cache ไว้บน Redis นั้นด้วยพลังของ Spring framework ทำให้เราสามารถพัฒนา application ได้ง่ายด้วยการ Config เพียงเล็กน้อยเท่านั้น แต่ก็ยังมีคุณสมบัติอื่นๆ อีกของ Spring Session ที่บทความนี้ยังไม่ได้กล่าวถึง ก็สามารถไปลองกันได้ 🤪

--

--

Phayao Boonon
Phayao Boonon

Written by Phayao Boonon

Software Engineer 👨🏻‍💻 Stay Hungry Stay Foolish

No responses yet