【问题标题】:How should I track the last active time of an user using graphql JWT? [duplicate]我应该如何使用 graphql JWT 跟踪用户的最后活动时间? [复制]
【发布时间】:2019-11-26 11:33:32
【问题描述】:

我正在记录用户登录信息,包括操作系统、浏览器、IP 和设备。我想在 30 天无活动期后删除它。问题是我的用户使用智能手机,他们在登录后几乎不会重新登录。我像这样覆盖了 graphql_jwt.JSONWebTokenMutation:

class ObtainJSONWebToken(graphql_jwt.JSONWebTokenMutation):
    class Arguments:
        push_token = graphene.String()

    user = graphene.Field(UserType)

    @classmethod
    def resolve(cls, root, info, push_token=None, **kwargs):
        ip, is_routable = get_client_ip(info.context, ['HTTP_X_FORWARDED_FOR', 'X_FORWARDED_FOR', 'REMOTE_ADDR'])
        ua_string = info.context.META['HTTP_USER_AGENT']
        user_agent = parse(ua_string)
        if user_agent.is_pc is True:
            device = 'Desktop'
        else:
            device = user_agent.device.family
        OS = user_agent.os.family + ' ' + user_agent.os.version_string
        browser = user_agent.browser.family + ' ' + user_agent.browser.version_string

        try:
            login_info = models.UserLoginInfo.objects.get(user=info.context.user, ip=ip, device=device,
                push_token=push_token, OS=OS, browser=browser)
            login_info.save()
        except models.UserLoginInfo.DoesNotExist:
            if push_token is not None:
                try:
                    duplicated_push_token_info = models.UserLoginInfo.objects.get(push_token=push_token)
                    duplicated_push_token_info.push_token = None
                    duplicated_push_token_info.save()
                except models.UserLoginInfo.DoesNotExist:
                    pass
            print(ip, device, OS, browser)
            login_info = models.UserLoginInfo(user=info.context.user, ip=ip, device=device,
                push_token=push_token, OS=OS, browser=browser)
            login_info.save()
        info.context.user.last_login = login_info.last_login
        info.context.user.save()

        return cls(user=info.context.user)

但我很快就发现了一个问题。正如我上面提到的,上次登录时间仅在用户登录时更新。所以我不能删除过去 30 天的 UserLoginInfo。那么我应该如何使用 graphql jwt 更新用户的上次活动时间呢?

我在每个需要身份验证的请求的 Authorization 标头中都包含一个 JWT 令牌。它由 graphql_jwt 自动处理。我所做的就是使用@login_required 装饰器。但我想覆盖 @login_required 的解析器。

【问题讨论】:

    标签: django jwt graphene-python


    【解决方案1】:

    更新用户上次活动时间的最佳位置是中间件,因为发出的每个请求都经过它,因此您可以确信任何活动都被跟踪。

    例如覆盖 login_required 装饰器只会影响使用它的端点,如果使用多个这样的装饰端点来解析 graphql 查询,每个端点都将访问 db 以更新最后一个活动时间,因此会导致不必要的服务器负载。

    Django 最后一个活跃的中间件示例:

    class UpdateLastActivityMiddleware(object):
       def __init__(self, get_response):
          self.get_response = get_response
    
       def __call__(self, request):
          if request.user.is_authenticated:
             User.objects.filter(pk=request.user.id) \
                         .update(last_activity=timezone.now())
          response = self.get_response(request)
    
          return response
    

    身份验证中间件之后包含它:

    
    MIDDLEWARE = [
        ...
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'your_package.middleware.UpdateLastActivityMiddleware',
        ...
    ]
    

    注意:它不是石墨烯中间件,因为它是在每个字段分辨率上调用的,但最后一个活动应该在每个请求中更新一次(这正是 django 中间件提供的)。

    【讨论】:

      猜你喜欢
      • 2020-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-31
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多