เพื่อทำความเข้าใจแนวคิดพื้นฐานที่อยู่เบื้องหลังการแคชเซสชันฝั่งเซิร์ฟเวอร์ คุณจะต้องใช้แอปพลิเคชันขนาดเล็ก โดยใช้ 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 ได้
ตัวอย่างเช่น ในแต่ละครั้งที่มีการกล่าวถึงตำแหน่งข้อมูล 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 ซึ่งสรุปลักษณะการทำงานดังกล่าว