使用JavaScript API访问ArcGIS Online中的安全FeatureLayer

4

我正在使用低代码平台(Mendix)构建Web应用程序。 我通过ArcGIS JavaScript API v4.19将Web应用程序与ArcGIS在线资源连接起来,一切都进行得非常顺利。

当我想要通过ArcGIS JavaScript API加载特定的受保护 ArcGIS online内容时,特别是来自受保护的某些FeatureLayer时,挑战出现了。我查阅了文档,发现最好的方法是所谓的“应用程序登录”。 为此,我想基于客户端ID和客户端秘钥设置OAuth应用程序登录。有了这两个,我可以通过AOuth获取有效令牌,并使用该令牌通过JavaScript API将令牌提供给IdentityManager以访问内容。

目前出错的地方在于,我似乎无法找到在ArcGIS online端明确指定可以通过此应用程序登录访问此特定受保护FeatureLayer的位置,因此,目前我收到错误消息,即有效令牌和应用程序ID无权访问资源,即受保护的FeatureLayer的终点。

请问有人知道如何将ArcGIS online中的受保护FeatureLayer关联到应用程序登录吗?

编辑10-6-2021:添加代码示例

在成功根据客户端ID和客户端秘钥在服务器端检索到有效令牌后,我使用以下方式在ArcGIS JavaScript API中使用客户端ID(= AppID)和令牌:

const token = {
    server: "http://www.arcgis.com",
    userId: <AppID>,
    token:
        <valid token retrieved via OAuth generateToken request,
    ssl: true,
    expires: 7200
};
IdentityManager.registerToken(token);

仅实现这一项会在尝试访问受保护的要素图层时出现错误:

identity-manager:not-authorized。"您当前登录为:AppID,您无权访问此资源:https://server/someid/arcgis/rest/services/somefeatureserver/FeatureServer/0

我还读到有时可能需要以下内容,因此也添加了:

const idString = JSON.stringify(IdentityManager.toJSON());
console.debug("idString: " + idString);
IdentityManager.initialize(idString);

这样做可以解决错误,但会再次弹出登录弹窗。
然后像下面这样声明该层:
const layer = new FeatureLayer({
    // URL to the service
    url: layerObj.layerURLStatic
    definitionExpression: queryDefinition,
    featureReduction: clusterConfig && { type: "cluster" },
    popupTemplate: {
        title: "{" + inAttributeTitle + "}",
        content: [
            {
                type: "fields", // FieldsContentElement
                fieldInfos
            }
        ],
        actions: [
            {
                title: props.intButtonLabel,
                id: btnId,
                className: props.intButtonClass + intButtonIconClass,
                type: "button"
            }
        ]
    },
    outFields: ["*"]
});

webMap.add(layer);

你想让应用程序用户提供client_id和client_secret,然后一旦他们这样做,层就会加载吗?还是你想在幕后使用自己的方式,并以此方式加载层(这意味着层只显示,UI中不需要用户登录)? - Seth Lutske
嗨Seth,感谢您的评论!应用程序已经提供了client_id + client_secret。一旦图层加载完成,我就会收到错误:identit-manager:not-authorized。我猜这是因为该层可通过此应用程序类型的登录访问。不确定在ArcGIS Online方面应该设置在哪里,Esri的文档在身份验证方面并不是最好的。 - Ivo Sturm
1
你能展示一些代码,说明你是如何使用你的client_id和client_secret的吗?以及你是如何声明你的layer的?当然不要展示秘密本身,只需展示带有变量名称的代码即可。 - Seth Lutske
嗨,塞斯,我添加了一些样例。 - Ivo Sturm
尝试过了,但没有起作用。 - Ivo Sturm
显示剩余3条评论
1个回答

1
这里有一段代码片段,用于生成令牌并在IdentityManager中进行注册:
IdentityManager = require('esri/identity/IdentityManager')
function login(user, password){
  var serverInfo = {
    "server": "https://www.arcgis.com",
    "tokenServiceUrl" : "https://www.arcgis.com/sharing/generateToken"
  };
  var userInfo = {
    username : user,
    password : password
  }
  IdentityManager.generateToken(serverInfo, userInfo).then(function (response){
      response.server = serverInfo.server;
      response.userId = user;
      IdentityManager.registerToken(response);
  });
}

我不确定你如何将其嵌入你的应用程序中,但是当应用程序运行时,如果你将示例粘贴到开发工具控制台中,则示例应该可以工作。
此外,据我所知,userId属性是用于arcgis在线用户名,而不是appId。
正如Shaked所指出的那样,如果在图层URL中附加“?token=[token_value]”,则可能无需注册令牌即可查询图层。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接