使用中间件将 UUID 存储在会话中

Posted

技术标签:

【中文标题】使用中间件将 UUID 存储在会话中【英文标题】:store UUID in session using middleware 【发布时间】:2021-08-23 14:34:59 【问题描述】:

我想用 UUID 标记所有请求 (如果请求一开始就没有)。

我想把 UUID 存储在会话中,所以我写了这个中间件。

class MachineIDMiddleware:
    """
    tags requests with machine UUIDs.
    The machine-ID is set in the session.
    """

    MID_KEY = "machine_id"

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        print(request.session.get(self.MID_KEY))
        if self.MID_KEY not in request.session:
            # set the machine-ID for the request
            # if it has not been set already (making
            # sure that it is serializable).
            next_id = str(uuid.uuid4())
            request.session[self.MID_KEY] = next_id
        return self.get_response(request)

但是,从我的客户那里,我注意到每个请求的 UUID 都在不断变化。 从我的客户那里,我注意到sessionid cookie 也会随着每个请求而改变。

因此,为每个请求生成了一个新的 UUID。 不过,这不是我想要的。我只想为每个人(可能是匿名的)维护一个 UUID。

我怎样才能做到这一点? 非常感谢!

编辑

export const Adapter = axios.create(
  baseURL: baseURL,
  headers: 
    "Content-Type": "application/json"
  
);

Adapter.interceptors.request.use(
  (request) => 
    const token = tokenSelector(store.getState());
    if (token) 
      request.headers.Authorization = `Token $token`;
    
    return request;
  ,
  (error) => 
    return Promise.reject(error);
  
);

Adapter.interceptors.response.use(
  (response) => 
    return response;
  ,
  (error) => 
    // handle unauthorized errors.
    if (error.response.status === 401) 
      store.dispatch(clearToken());
      history.replace(SLUGS.login);
    
    // handle internal server errors.
    if (error.response.status === 500) 
      toast.dark("Something went wrong. Please try again later.");
    
    // handle server ratelimits.
    if (error.response.status === 429) 
      toast.dark("You are being ratelimited.");
    
    return Promise.reject(error);
  
);

这就是我从前端发送请求的方式。 我用axios。我在开发者工具面板中检查了我的 cookie 并且在那里看不到sessionid cookie。

编辑 2

Chrome devtools 向我显示以下错误,但不是 正确设置 sessionid cookie。可能是这个原因吗?

** 答案(已解决)** 在我的 settings.py 文件中设置以下变量 确保 chrome 正确设置了 cookie。

# CORS configuration
ALLOWED_HOSTS = ["*"]
CORS_ALLOW_ALL_ORIGINS = True
CSRF_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
CORS_ALLOW_CREDENTIALS = True
SESSION_COOKIE_HTTPONLY = False

【问题讨论】:

您可能没有从客户端维护会话。您如何向客户提出请求? with axios.. 抱歉,我不知道我必须从客户端维护一个会话。我该怎么做? 我进行了编辑!请检查一下!谢谢! 这能回答你的问题吗? Make Axios send cookies in its requests automatically(调用axios.create时在配置中设置withCredentials: true 非常感谢!你的参考帮助了我。我已经解决了这个问题(我在我的编辑中提到了如何) 【参考方案1】:

这是您正确的__call__ 函数

def __call__(self, request):
     print(request.session.get("MID_KEY"))
     if "MID_KEY" not in request.session:  
             next_id = str(uuid.uuid4())    
             request.session["MID_KEY"] = next_id.   
     return self.get_response(request)

键应该是字符串(常量)而不是变量

【讨论】:

很抱歉,但我希望会话密钥保持不变。这样,我可以跟踪匿名用户。这不会那样做。 它会这样做,因为对于每个会话,MID_KEY 的值会有所不同,但键是相同的,这就是键/值存储背后的想法。

以上是关于使用中间件将 UUID 存储在会话中的主要内容,如果未能解决你的问题,请参考以下文章

通过中间件方法访问Laravel会话 - 会话存储未根据请求设置

OWIN 中间件可以使用 http 会话吗?

如何在中间件中使用会话来始终检查用户是不是登录

SSL 和中间人的误解

使用Redis实现分布式会话

解析中间人攻击(3/4)---会话劫持