用中国漢語將以下句子重新表達一次(只需要一種選項):使用向量瓦片和 Azure AD 認證(使用 Node.js 創建伺服器)

首先

当向用户提供自己的矢量瓦片数据时,您会为数据添加何种认证?

我想在这里谈一谈我给矢量瓦片添加Azure AD身份验证的经验。虽然这项工作是一段时间之前完成的,但我想记录下我记得的内容以供分享。我觉得记录的重点不在于细节,而在于记录方针和有参考价值的代码位置。如果您有任何反馈、改进建议或指导意见,敬请告知!

顺便提一下,由于这项工作是在开发环境中完成的,所以还没有应用到真正的互联网上的公开服务器上。

为什么需要验证?

如果要公开自己创建的矢量瓦片,我认为不需要进行认证。然而,如果其中包含不想向大众公开的数据或者希望通过收费提供服务,就需要对访问者进行认证。在我处理的数据中,同事在使用数据时也考虑到了用户认证的必要性,所以我尝试了矢量瓦片的认证。

既有服务中的矢量瓦片访问限制等

在进行工作之前,我稍微查看了一下现有服务的访问限制情况。可能会有一些错误。

    • ArcGSI Online

ArcGISサーバーでホストしているタイルのうち、一般に公開していないものを見てみました。ArcGISオンラインへのログイン後、ベクトルタイル地図を見ている様子を観察すると、ベクトルタイルのURLリクエストにクエリをつけて(?token=…)、アクセスを管理している様子。

MapBox

AccessTokenとURLによる制約ということでしょうか。TokenはJSON Web Tokensを使っているようです。

https://docs.mapbox.com/help/getting-started/access-tokens/
https://docs.mapbox.com/help/troubleshooting/how-to-use-mapbox-securely/

国土地理院のベクトルタイル

pbfタイルで提供されていますが、パスワードや認証などは必要なさそうです。

英国Ordnance Surveyのベクトルタイル

アカウントがないのでわからないのですが、OS Data Hubの文書をみると OAuth 2を使っていそうです。

https://osdatahub.os.uk/docs/vts/overview

我工作的條件

虽然每个矢量瓦片服务器的情况都可能不同,但我是通过nodejs/express服务器使用https协议来传送矢量瓦片。本次工作的主要要求是以下两点。

    • nodejsでのサーバー構築が必要。これは、ベクトルデータのサイズが大きいためデータをmbtilesで格納しており、pbfタイルのリクエストに対して、nodejs/expressサーバーのルーティングと @mapbox/mbtiles というnpmモジュールで対応していたためです。unvt/onyxの仕組みを使います。

 

    認証はAzure AD認証をつかう。

环境

    • サーバーの環境:

RHEL 8.4
nodejs: ver12.21.0 (1年くらい前の作業で、mapbox/mbtilsの当時のバージョンが新しいnodejsで動かなかったため)

SSH/TLS: httpsのための認証は内部用のものをもらった
Azure AD Portalでの登録:ここは同僚が作業してくれて、テナントIDやシークレットをくれました。

过程

0. 第0步,在单页面应用程序教程中熟悉一下(可选)

由于我在这个领域没有经验,所以我首先尝试适应了Azure AD身份验证和使用msal包的机制。(注意:我使用的是MSAL(Microsoft Authentication Library),而不是ADAL(Azure Directory Authentication Library))

微软教程在这里:
https://docs.microsoft.com/zh-cn/azure/active-directory/develop/tutorial-v2-javascript-spa
https://github.com/Azure-Samples/ms-identity-node

我使用同事提供的客户ID、权限和客户密钥等信息,在内部环境中进行了实验。我对实验结果的理解大致如下。

(从这一步开始下面的内容大部分都是我个人的笔记,如果不需要的话请跳过阅读。)

    • msalのconfig変数(auth(クライアントID、オーソリティ、クライアントシークレット)とsystem(ログのオプション))を作る。

https://github.com/Azure-Samples/ms-identity-node/blob/main/index.js#L13-L28

msal applicationオブジェクトの変数をつくる。前で作ったコンフィグ情報で、msalConfidentialClientApplication(作った変数) として、msal applicationオブジェクトの変数に代入する。

https://github.com/Azure-Samples/ms-identity-node/blob/main/index.js#L31

ルーティング。ルート(/)にきたリクエストを、{msal application オブジェクト}.getAuthCodeUrl(リダイレクトURLやスコープを持った変数)で得られるアドレスにリダイレクトする。(そのあとログインするとリダイレクトされると思われる。)

https://github.com/Azure-Samples/ms-identity-node/blob/main/index.js#L36-L46

redirectのアドレスに帰ってきたら(帰ってくるときのrequestにcodeがついている)、codeでtokenRequestの変数をつくって、(msal application オブジェクト).acquireTokenByCode(tokenRequest)として、トークンをとる。コードを使ってトークンをゲットしたということだろう。(サンプルコードではこのトークンをサーバー側で表示するようになっています。)

https://github.com/Azure-Samples/ms-identity-node/blob/main/index.js#L48-L62

简单来说,就是通过AuthCodeURL获取AuthCode并使用该代码登录,然后在重定向后使用AuthCode获取Token,是这样的吗?

当查询有关OAuth的说明时,我们得知idToken和AccessToken是不同的,但首先会返回代码和idToken,然后我们可以使用它们来获取accessToken和idToken。

第一步: 构建Nodejs的express应用程序

接着来说,当我搜索nodejs express和Azure AD 身份验证示例时,我找到了一个名为“使用 Microsoft Graph 构建 Node.js Express 应用程序”的教程。该教程演示了如何从 Microsoft Graph API 获取日历信息,并涉及到了 Azure AD 身份验证步骤,看起来很实用。我将通过 Graph API 仅获取用户名等基本信息。

按照教程的步骤,我们将建立一个Node.js Express服务器。在教程的GitHub存储库中的demo文件夹中,有教程的代码,我们可以从这里下载并开始操作。https://github.com/microsoftgraph/msgraph-training-nodeexpressapp/tree/main/demo/graph-tutorial

如果详细描述这部分内容,将涉及到有关MSAL而不是矢量瓦片的讨论,所以不需要深入探讨,但需要注意以下几点。

从这个步骤开始,下面半数以上的部分都像是我自己的笔记,如果不需要的话,请跳过阅读。

    • msal application objectは、app.locals.msalClientに格納されている。

 

    • サーバーではメモリストレージを使ってログインしたユーザーを保存している。デモなので、メモリ(app.locals)を使っている点には注意。本番環境では要検討。(これはPM2でクラスターモードで2以上にしても問題になる原因です。)

Step1と違って、認証関係のコードはroutes/auth.jsに書かれている。authのcallbackプロセスでは以下のようなことをやっていました。

トークンリクエストで帰ってきたresponseのresponse.account.homeAccountIdをreq.session.userIdとセッションに記録している。さらにgraphからかえってきたユーザーの詳細情報を情報を、ユーザーストレージに入れている(req.app.locals.users[req.session.userId])。そしてルートに(/)リダイレクトする。

そんな感じで、ユーザー情報をセッションに保存しているようでしたが、これを使って、どのようにアクセス管理をしているかは、calendar.jsをみてみました。ここにリクエストがくると、以下のような感じでした。

req.session.userIdがないと、ログインしなさいということで、ルートにリダイレクトされる。
req.session.userIdがあれば、変数userとしてreq.app.locals.users[req.session.userId]がとってこられる。そして、このuserやmsal application objectをつかってとってきたgraphの情報が返される。

尽管这与矢量瓦片无关,但看起来是以这种方式对用户进行身份验证。
此Microsoft教程在2021年4月更新至1.8版本,而基于先前版本参考而创建的开发环境矢量瓦片服务器是 https://github.com/un-vector-tile-toolkit/coesite。我们将其命名为coesite,表示即使在比unvt/onyx受限的环境下,也希望它能够努力。(虽然我不知道onyx的来源,但如果它表示SiO2的成分物质,那么在超高压下会变成coesite石。)

步骤2:将路线添加至矢量瓦片。

由于用户认证和登录服务器的形式已经建立起来,接下来要做的是设置到矢量瓦片的路由。

为了传送矢量瓦片,我们在路由(route)中创建了一个路由(route)。就像这样的图像(https://github.com/ubukawa/server-test-01/blob/main/routes/VT.js),我们在步骤2中添加了用户确认。虽然有点不完整,但我们在这里尝试了一下(https://github.com/un-vector-tile-toolkit/coesite/blob/main/routes/vtile-m.js)。然后,在app.js中加入var vtileMRouter = require(‘./routes/(created file name)’)和app.use(‘/(path)’,vtileMRouter)。
不要忘记在app.js中进行CORS设置。

第三步。转为HTTPS(并使用PM2运行)。

由于Microsoft的教程是通过本地主机的http进行托管的,所以我们需要在app.js中添加spdy模块来进行https化(请提前定义密钥路径和端口)。这样服务器就可以通过https进行操作了。为了在后台运行,我们需要使用PM2进行执行。

//for https
spdy.createServer({
    key: fs.readFileSync(privkeyPath),
   cert: fs.readFileSync(fullchainPath)
}, app).listen(port)

其他:PM2的有趣小事。

在config文件夹中创建一个名为default-0.hjson的空文件。

为了能够读取config/default.hjson文件中的对象,在config包中进行配置。但是当执行PM2时,出现了错误。我提前创建了一个名为空的default-0.hjson文件,然后它就能正常运行了。

集群模式

在执行pm2时,可以使用-i选项指定群集的数量。但是,由于用户信息存储在会话内存中,所以在另一个群集中无法访问内存,因此需要重新登录。在修复内存问题之前,我们将使用群集模式1。

问题

到目前为止,我已经成功创建了一个能够登录并查看矢量切片地图的服务器。然而,仍然存在一些问题,我正在进行解决。

跨出源的认证

目前,我们正在进行与跨域问题的调整。
如果没有认证,只需使用 app.use(cors()) 就可以从其他源使用矢量切片,但如果涉及跨域认证,可能需要进一步调整。

举个例子,请求方似乎需要在CORS中将凭据设置为include,而响应方似乎需要将Access-Control-Allow-Credentials设置为true(就像这个页面上的说明https://web.dev/cross-origin-resource-sharing/)。

因此,在服务器端我们不使用app.use(cors()),而是使用其他方式。

const corsOption = {
 origin: '*',
 credentials: true
}
app.use(cors(corsOption))

可能需要考虑年龄。

此外,地图库方面,我认为在transformRequest中也需要将credentials设置为’include’,无论是在Mapbox的请求参数还是在MapLibre的请求参数中,都需要以相同的方式进行操作。

但是,由于这些事情仍然没有取得良好的效果,所以我正在进行各种实验。

会话存储

由于当前将用户信息存储在会话内存中,我们计划为正式环境准备会话存储。

总结

我记录了我在添加身份验证到矢量切片服务器上的经历。

这个话题主要是关于如何在网页服务器中添加认证,所以与矢量瓦片没有太大关系。可能专业人士可以轻松完成,但作为初学者的尝试记录,希望能够得到温暖的眼光。

我在nodejs中完成了,但是如果传送的数据量不大的话,可以考虑使用经常使用的web服务器,比如apache或者nginx,这样参考资料也会更多,更容易操作。

感谢辞

我为与我一起合作的同事深表感激。(虽然你可能看不懂日语…)

可以参考的资料等

本文中附有链接。

广告
将在 10 秒后关闭
bannerAds