1

我正在开发一个身份验证插件,该插件使用 JWT 解析来获取详细信息并更新 Mesh 中的用户。
我还想创建一个新节点并将其附加到网格中的用户,使用user.setNodeReference()// 这是我如何将用户关联到节点吗?

问题是当我返回映射结果时,如果我创建用户配置文件节点,我会看到mapToken()使用与以前相同的标记再次调用的方法,就像它在循环一样。我发现这是由于路由器中的“重试”功能

如果我没有将节点附加到,user.nodeReference()那么它会按预期进行。

想法?

    @Override
    public MappingResult mapToken(HttpServerRequest req, String uuid, JsonObject token) {
        MappingResult result = new MappingResult();

        if (uuid == null) {
            log.info("First time login of the user");
        } else {
            log.info("Already synced user is logging in.");
        }

        log.info("Mapping user in plugin");
        printToken(token);
        String username = extractUsername(token).get();
        UserUpdateRequest user = new UserUpdateRequest();
        user.setUsername(username);
        user.setEmailAddress(username);
        user.setFirstname(token.getString("firstname", "firstname"));
        user.setLastname(token.getString("lastname", "lastname"));

        // TODO: Stop the infinite loop
        if (uuid == null) {
            log.info("Creating profile node");
            user.setNodeReference(createProfileNode(username, token));
        } else {
            log.info("Updating profile node");
            //updateProfileNode(uuid, token);
        }

        result.setUser(user);

...
}

    private ExpandableNode createProfileNode(String username, JsonObject token) {

        NodeCreateRequest nodeCreateRequest = new NodeCreateRequest()
                .setLanguage("en")
                .setSchemaName(getConfig().getProfileSchema())
                .setParentNodeUuid(getConfig().getProfileParentUuid());
        FieldMap fields = nodeCreateRequest.getFields();
        fields.putString("name", username);
        fillProfileFieldMappedValues(fields, token);
        nodeCreateRequest.setFields(fields);
        return this.adminClient.createNode(getConfig().getProjectName(), nodeCreateRequest).blockingGet();
    }

更新

我检查了 jti & iat - 令牌包含两者。
我想也许如果我订阅 USER_CREATED 事件,我可以在创建用户后添加一个配置文件节点。
但我没有看到这曾经被执行过。我可能错误地订阅了本地事件总线。

getRxVertx().eventBus().localConsumer(MeshEvent.USER_CREATED.getAddress()).handler((message) -> {
  try {
    String uuid = JsonUtil.getMapper().readTree(message.body().toString()).get("uuid").asText();
                adminClient().findUserByUuid(uuid).toSingle().doAfterSuccess(u -> {              
      u.setNodeReference(createProfileNode(u.getUuid()).getBody());                
    }).doOnError(e -> {
        log.error("Failed to create user profile node: {}", e);      
      });           
    } catch (IOException e) {
        log.error("Failed to deserialize user: {}", e);
    }
});

另外,我不需要设置user.setNodeReference()来重现错误,我只需要尝试在mapToken方法中创建一个新节点。它将重试创建用户 10 倍,然后以 http 500 出错。
我将打开日志以查看是否可以获得更多详细信息。

更新 我发现如果我首先在mapToken函数中创建用户,然后为配置文件创建一个节点,我可以将它添加到user.setNodeReference()但我从未在内容浏览器中看到该节点 [我在 `{project}/ profile/{userProfileNode}],我在检索用户时看不到节点引用。

但是日志显示该节点已成功创建。

4

1 回答 1

1

您的令牌是否包含令牌 ID?(jti 或 iat)。Mesh 将使用这些值之一来确定是否需要为令牌重新运行键映射。这背后的想法是避免对未更改的令牌的虚假映射调用。我怀疑您的令牌没有通过此检查,并且将始终传递给映射器插件。

如果我能看到一些日志,我可能会给你更多的提示。

于 2019-11-05T16:10:54.047 回答