เพื่อทำความเข้าใจแนวคิดพื้นฐานที่อยู่เบื้องหลังการแคชเซสชันฝั่งเซิร์ฟเวอร์ คุณจะต้องใช้แอปพลิเคชันขนาดเล็ก โดยใช้ Flask ซึ่งเป็นไมโครเฟรมเวิร์กสำหรับการพัฒนาเว็บไซต์ใน Python เนื่องจากเราจะให้ความสำคัญไปที่แนวคิด ไม่ใช่รายละเอียดของเฟรมเวิร์กและภาษาที่กำหนด คุณสามารถแปลตัวอย่างต่างๆ ในเว็บเฟรมเวิร์กและภาษาเขียนโปรแกรมตามที่คุณต้องการ
หากคุณต้องการเริ่มต้นใช้งาน Flask ให้ทำตาม คำแนะนำการติดตั้ง และ คู่มือเริ่มต้นใช้งานฉบับย่อ
ด้านล่างนี้เป็นแอปพลิเคชันพื้นฐานที่ช่วยให้คุณเข้าและออกจากระบบ:
syntax: python
import os
from flask import Flask, session, redirect, escape, request
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY', default=None)
@app.route('/')
def index():
if 'username' in session:
return 'Logged in as %s' % escape(session['username'])
return 'You are not logged in'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect('/')
return '''
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect('/')
ตัวอย่างที่เหลือจะเป็นไปตามส่วนย่อยนี้ สามารถดูตัวอย่างโค้ดทั้งหมดได้ในคลังเนื้อหานี้
หากคุณติดตั้ง Flask แล้ว และต้องการบูตแอปนี้ ให้คัดลอกโค้ดไปวางลงในไฟล์ที่ชื่อว่า example-1.py จากนั้นคุณจะต้องส่งออกตัวแปรสภาพแวดล้อม 2 ตัวแปร ได้แก่ FLASK_APP ที่ตั้งเป็น example-1.py และ SECRET_KEY ที่ตั้งเป็นสตริงแบบสุ่ม เช่น Y0PJWblKsg1axM4fGW หากคุณต้องการความช่วยเหลือในการตั้งค่าตัวแปรสภาพแวดล้อม ให้ดูที่ คู่มือเริ่มต้นใช้งานฉบับย่อ ของ Flask
เมื่อคุณพร้อมแล้ว ให้เรียกใช้คำสั่งนี้:
syntax: shell
$ flask run -h 0.0.0.0 -p 5000 --reload
จากนั้นไปที่ http://your_flask_endpoint:5000 ซึ่งคุณจะได้เห็นว่าแอปกำลังทำงาน คุณจะต้องเปลี่ยน your_flask_endpoint เป็นชื่อ DNS สาธารณะของ EC2 instance ของคุณ ตามที่คุณได้ดำเนินการไว้ในข้อกำหนด
มี 3 เส้นทางที่พร้อมใช้งาน ได้แก่ “/”, “/login” และ “/logout” เข้าไปให้ครบทุกเส้นทางตามลำดับ และคุณจะเริ่มเข้าใจลักษณะการทำงานพื้นฐาน
ระยะเวลาที่ใช้ในการศึกษาโมดูล: 60 - 90 นาที
ตัวอย่างจะใช้คุกกี้เพื่อจัดเก็บชื่อผู้ใช้ เมื่อคุณเข้าไปในแอปพลิเคชันเป็นครั้งแรก จะไม่มีชื่อผู้ใช้จัดเก็บอยู่ในอ็อบเจ็กต์เซสชัน เมื่อคุณไปที่ “/login” และป้อนชื่อผู้ใช้ ระบบจะจัดเก็บค่าในคุกกี้ที่ลงชื่อไว้ และระบบจะนำคุณเปลี่ยนเส้นทางไปยังหน้าหลัก จากนั้น หากคุณไปที่ “/logout” ระบบจะลบชื่อผู้ใช้ออกจากเซสชัน และคุณจะกลับไปยังหน้าที่คุณเริ่มต้น
คุณจะต้องขยายแอปพลิเคชันพื้นฐานนี้ด้วยเซสชันฝั่งเซิร์ฟเวอร์ แต่อันดับแรก คุณจะต้องแน่ใจว่าคุณสามารถเชื่อมต่อกับ Redis ได้
syntax: shell
$ export REDIS_URL="redis://your_redis_endpoint:6379"
syntax: shell
$ python
syntax: python
>>> import redis
>>> client = redis.Redis.from_url('redis://your_redis_endpoint:6379')
>>> client.ping()
**True**
หากคำสั่งหยุดการตอบสนอง ก็เป็นไปได้ว่าคุณถูกบล็อกโดยการตั้งค่ากลุ่มความปลอดภัย ยืนยันว่า EC2 instance ของคุณสามารถเข้าถึงกลุ่มความปลอดภัยที่มอบหมายไปยังอินสแตนซ์ ElastiCache ของคุณ ตัวอย่างเช่น สมมติว่า EC2 instance ของคุณได้มีการมอบหมายไปยังกลุ่มความปลอดภัยเริ่มต้น ตอนนี้คุณจะสามารถปรับเปลี่ยนกลุ่มความปลอดภัยของอินสแตนซ์ Amazon ElastiCache ของคุณและเพิ่มกฎ TCP แบบกำหนดเองที่อนุญาตให้มีการเชื่อมต่อบนพอร์ต 6379 จากอินสแตนซ์ใดก็ได้ในกลุ่มความปลอดภัยเริ่มต้น:
ในแหล่งที่มา คุณสามารถเริ่มพิมพ์ชื่อกลุ่มความปลอดภัย แล้วจะสามารถคลิกบนรหัสกลุ่มความปลอดภัยได้ หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับกลุ่มความปลอดภัย คุณสามารถดูเอกสารประกอบหรือข้อมูลอ้างอิงกฎของกลุ่มความปลอดภัย
กลับไปที่ตัวอย่าง ตอนนี้ คุณจะต้องเริ่มทำความเปลี่ยนแปลงเล็กน้อยที่จะช่วยให้คุณสามารถจัดเก็บข้อมูลเซสชันใน Redis ได้ นี่คือตัวอย่างที่สองพร้อมการเปลี่ยนแปลง:
syntax: python
import os
import redis
from flask import Flask, session, redirect, escape, request
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY', default=None)
# BEGIN NEW CODE - PART 1 #
REDIS_URL = os.environ.get('REDIS_URL')
store = redis.Redis.from_url(REDIS_URL)
# END NEW CODE - PART 1 #
@app.route('/')
def index():
if 'username' in session:
# BEGIN NEW CODE - PART 2 #
username = escape(session['username'])
visits = store.hincrby(username, 'visits', 1)
return '''
Logged in as {0}.<br>
Visits: {1}
'''.format(username, visits)
# END NEW CODE - PART 2 #
return 'You are not logged in'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect('/')
return '''
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>'''
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect('/')
ตอนนี้ ระบบได้นำเข้าและเริ่มต้น Redis แล้ว และดัชนีจะจัดการเพิ่มตัวนับและแสดงให้ผู้ใช้เห็น
โปรดทราบว่า คำสั่ง Redis ที่คุณใช้ในการเพิ่มตัวนับคือ HINCRBY นั่นเป็นเพราะว่า คุณกำลังใช้แฮช Redis สำหรับเซสชันของผู้ใช้แต่ละเซสชัน
ตอนนี้ คุณจะต้องตั้งค่า Time to Live (TTL) ให้กับเซสชันฝั่งเซิร์ฟเวอร์ ซึ่งเป็นบรรทัดโค้ดเสริมเพียงหนึ่งบรรทัด และส่วนย่อยนี้จะรวมเส้นทาง / เท่านั้น
syntax: python
...
@app.route('/')
def index():
if 'username' in session:
username = escape(session['username'])
visits = store.hincrby(username, 'visits', 1)
# BEGIN NEW CODE #
store.expire(username, 10)
# END NEW CODE #
return '''
Logged in as {0}.<br>
Visits: {1}
'''.format(username, visits)
return 'You are not logged in'
...
คีย์ที่จัดเก็บเซสชันจะหมดอายุภายในเวลา 10 วินาที ส่วนนี้มี TTL ที่สั้นมากๆ แต่มีประโยชน์เฉพาะตัวอย่างนี้เท่านั้น หากคุณเรียกใช้แอปพลิเคชันตอนนี้ คุณจะเห็นว่าการเข้าชมดัชนีจะอัปเดตตัวนับการเข้าชมอย่างไร แต่หากคุณปล่อยให้เวลาผ่านไป 10 วินาทีโดยไม่มีการเข้าชมหน้านั้น ในการรีเฟรชครั้งต่อไป ตัวนับจะกลับมาที่ 1
ตัวอย่างสั้นๆ นี้เหมาะสมเพียงพอสำหรับการเรียนรู้พื้นฐานของเซสชันฝั่งเซิร์ฟเวอร์ แต่ในสถานการณ์จริง คุณจะต้องดำเนินการต่างกันออกไป กล่าวคือ จากการจัดเก็บชื่อผู้ใช้ คุณจะต้องสร้างและจัดเก็บโทเค็นเมื่อตรวจสอบความถูกต้องผู้ใช้แล้ว โทเค็นดังกล่าวจะแสดงแทนคีย์ Redis ที่จะจัดเก็บข้อมูลเซสชันฝั่งเซิร์ฟเวอร์ทั้งหมดไว้ นอกจากนี้ คุณอาจต้องสรุปลักษณะการทำงานบางส่วนที่แสดงที่นี่ เพื่อให้การเข้าถึงเซสชันฝั่งเซิร์ฟเวอร์สามารถรีเฟรช TTL ได้โดยคุณไม่จำเป็นต้องขัดจังหวะ ในคลังเนื้อหา คุณจะพบตัวอย่างที่มีคลาส SessionStore ซึ่งสรุปลักษณะการทำงานดังกล่าว
