Ruby on Rails基于Firestore自定义Session:reset_session清空集合问题
Firestore自定义Session存储异常:调用reset_session清空整个sessions集合
我基于Firestore实现了一个自定义Session存储,但调用reset_session执行登出操作时,整个sessions集合被意外清空。以下是我的实现代码:
require "google/cloud/firestore" class FirestoreSessionStore < ActionDispatch::Session::AbstractSecureStore def initialize app, options = {} super @firestore = Google::Cloud::Firestore.new @col = @firestore.col "sessions" end def find_session _req, session_id return [generate_sid, {}] if session_id.nil? doc = @col.doc session_id fields = doc.get.fields || {} [session_id, stringify_keys(fields)] end def write_session _req, session_id, new_session, _opts doc = @col.doc session_id doc.set new_session, merge: true session_id end def delete_session _req, session_id, _opts doc = @col.doc session_id doc.delete generate_sid end def stringify_keys hash new_hash = {} hash.each do |k, v| new_hash[k.to_s] = if v.is_a? Hash stringify_keys v else v end end new_hash end end
问题原因
当调用reset_session时,Rails可能会传入空值(nil或空字符串)作为session_id。此时@col.doc(session_id)会创建一个指向空文档ID的引用,而Firestore SDK在执行这个空ID文档的删除操作时,会错误地触发整个集合的删除逻辑,导致所有session数据被清空。
参考的谷歌云Ruby入门文档中,正确的实现会先校验session_id的有效性,避免此类情况发生。
解决方案
修改delete_session方法,先判断session_id是否有效,仅当session_id存在且非空时才执行删除操作:
def delete_session _req, session_id, _opts if session_id.present? doc = @col.doc session_id doc.delete end generate_sid end
同时建议加强find_session方法的校验逻辑,避免无效session_id引发的异常:
def find_session _req, session_id return [generate_sid, {}] if session_id.nil? || session_id.empty? doc = @col.doc session_id fields = doc.get.fields || {} [session_id, stringify_keys(fields)] end
内容的提问来源于stack exchange,提问作者Anonymous Duck
相关产品推荐
相关产品推荐

