【问题标题】:How to logout (ie, revoke, delete, or invalidate the tokens) for a user on an Aqueduct server?如何在 Aqueduct 服务器上为用户注销(即撤销、删除或使令牌无效)?
【发布时间】:2019-05-21 23:28:52
【问题描述】:

我知道如何实现注册用户的路由,以及如何用用户凭据换取访问令牌。这些都包含在官方tutorial 中。

如何使注册用户的访问令牌(和刷新令牌)失效。如果用户的帐户被盗,这对于注销和限制损害都是必要的。

我看到有一个方法

authServer.revokeAllGrantsForResourceOwner(identifier)

但我仍在研究如何从用户那里获取标识符,因为客户端应用程序知道用户名,但不知道服务器数据库中的用户 ID。最好只传递当前令牌并让服务器取消该用户的所有令牌。

【问题讨论】:

    标签: dart aqueduct dart-server


    【解决方案1】:

    如果您想撤销给定令牌的所有令牌,请从授权令牌中获取用户 ID 并对该用户的令牌运行删除查询:

    class TokenManagerController extends ResourceController {
      @Operation.delete()
      Future<Response> deleteTokens() async {
        final userId = request.authorization.ownerID;
    
        final query = Query<ManagedAuthToken>(context)
          ..where((token) => token.resourceOwner).identifiedBy(userId);
        final count = await query.delete();
    
        return Response.ok({"userId": userId, "tokensDeleted": count});
      }
    }
    

    并确保您链接授权人:

    router.route("/tokens")
          .link(() => Authorizer.bearer(authServer))
          .link(() => TokenManagerController(context));
    

    FWIW,我建议专门为此操作设置一个范围,该范围仅通过额外登录授予此场景。用户体验是用户必须再次输入密码。

    如果您只想删除一个令牌,只需运行删除查询,其中access_token = 授权标头中的令牌。

    class LogoutController extends ResourceController {
      @Operation.delete()
      Future<Response> deleteTokens(@Bind.header('authorization') String authHeader) async {
    
        final parser = AuthorizationBearerParser();
        final userToken = parser.parse(authHeader);
    
        final query = Query<ManagedAuthToken>(context)
          ..where((token) => token.accessToken).equalTo(userToken);
        final count = await query.delete();
    
        final userId = request.authorization.ownerID;
        return Response.ok({"userId": userId, "tokensDeleted": count});
      }
    }
    

    【讨论】:

    • 这很有帮助。谢谢你。不过,我可能不了解用户体验。在注销之前必须输入密码并不是常见的行为。这让我觉得上面的代码是针对比登出更特殊的情况。真的吗?要注销,我可能需要做的就是删除客户端的令牌。
    • 答案here 很有帮助,但我仍然有点不确定是否应该在注销时删除 Aqueduct 服务器上的令牌。在某种程度上,Aqueduct 服务器不是 RESTful(在我的理解中),因为它确实保存了用户令牌信息。
    • 啊,如果您只想删除一个令牌,只需运行一个删除查询,其中 access_token = 授权标头中的令牌。我不确定我是否遵循“RESTful”部分;令牌是存储在某处还是无状态令牌(例如 JWT)对 API 的无状态性没有影响。应用程序仍然是无状态的;您可以创建任意数量的实例,它们的行为都相同,您可以使用从 API 的一个实例收到的令牌与另一个实例。如果将数据存储在数据库中使您的 API 成为有状态的,那么任何应用程序都不会是无状态的。
    • 好的,我可以用..where((token) =&gt; token.accessToken).equalTo(userToken); 做到这一点。请求中的不记名令牌是否暴露在任何地方?它显然不在request.authorization 中。要获得userToken,我必须先使用@Bind.header('authorization'),然后使用AuthorizationBearerParser 来获得令牌。
    • 最后一个问题。我看不出只删除当前令牌和所有旧令牌之间的实际区别。有吗?
    猜你喜欢
    • 2018-09-21
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2014-03-26
    • 2021-02-09
    • 1970-01-01
    • 2017-10-03
    相关资源
    最近更新 更多