如何从前端接收来自Azure服务总线主题的通知?

huangapple go评论70阅读模式
英文:

How to get notification from azure service bus topic from frontend?

问题

我们正在使用 Azure 服务总线进行通知服务。在 Azure 门户中,已创建服务总线主题并在主题中可用消息。我正尝试使用 REST API 服务获取主题数据。

这是我目前拥有的代码。

import axios from 'axios';

const namespace = 'my-namespace';
const topicName = 'my-topic-name';
const subscriptionId = 'my-subscription-id';
const accesskey = 'my-access-key';

const baseurl = `https://${namespace}.servicebus.windoes.net`;
const url = `${baseurl}/${topicName}/subscriptions/${subscriptionId}`;
const headers = {
  Authorization: `SharedAccessSignature ${accesskey}`,
  'content-type': 'application/json',
}

const getDetails = async () => {
  try {
    const response = await axios.get(url, { headers });
    console.log('response', response.data);
  } catch (error) {
    console.error('error', error);
  }
}

export default getDetails;

我目前对前端所需的内容了解有限。我尝试使用 @azure/service-bus,但出现了 cant resolve 'os' in rhea,webpack < 5 used 错误。

因此,我尝试消除依赖关系并使用 https 服务。

我目前遇到 401 未经授权 错误。您能指导我在哪里出错了吗?

根据建议更新的代码:

import axios from 'axios';
import { SHA256 } from 'crypto-js';

const sbName = 'my-sb-name';
const topicName = 'my-topic-name';
const sharedAccessKey = 'my-shared-access-key';
const sharedAccessName = 'RootManagerSharedAccessKey';
const expiry = Math.floor(Date.now() / 1000) + 10000;
const baseUrl = `https://${sbName}.servicebus.windows.net`;
const url = `${baseUrl}/${topicName}`;
const toSign = `${url}\n${expiry.toString()}`;
const signature = SHA256(toSign).toString();
const encodedSignature = encodeURIComponent(signature);
const authFormat = `SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}`;
const auth = authFormat
  .replace('{0}', encodedSignature)
  .replace('{1}', expiry.toString())
  .replace('{2}', sharedAccessName)
  .replace('{3}', url);

console.log(auth);

const headers = {
  Authorization: auth,
  'Content-Type': 'application/json',
};

const getDetails = async () => {
  try {
    const response = await axios.get(url, { headers });
    console.log('Queue Details:', response.data);
    // 处理响应或使用检索到的队列详情更新 UI
  } catch (error) {
    console.error('Error retrieving queue details:', error);
  }
};

// 调用函数以获取队列详情
export default getDetails;

这会产生错误:401 未经授权

英文:

we are using azure-service-bus for notification services. in azure portal., service bus topic has been created and message is available in topic. Iam trying to use REST API services to get the topic data.

This is the code I have currently.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

import axios from &#39;axios&#39;;

const namespace = &#39;my-namespace&#39;;
const topicName = &#39;my-topic-name&#39;;
const subscriptionId = &#39;my-subscription-id&#39;;
const accesskey = &#39;my-access-key&#39;;

const baseurl = `https://${namespace}.servicebus.windoes.net`;
const url = `${baseurl}/${topicName}/subscriptions/${subscriptionId}`;
const headers = {
  Authorization: `SharedAccessSignature ${accesskey}`,
  &#39;content-type&#39;: &#39;application/json&#39;,
}

const getDetails = async () =&gt; {
  try {
    const response = await axios.get(url, { headers });
    console.log(&#39;response&#39;, response.data);
  } catch (error) {
    console.error(&#39;error&#39;, error);
  }
}

export default getDetails;

<!-- end snippet -->

I currently have very limited understanding on what is required in frontend. I was trying to use @azure/service-bus., but it is giving error cant resolve &#39;os&#39; in rhea., webpack &lt; 5 used error.

Hence I tried to eliminate the dependency and used https services.

iam currentlu getting 401 unauthorized error.

can you guide me where iam doing wrong?

updated code as per suggestions:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

import axios from &#39;axios&#39;;
import { SHA256 } from &#39;crypto-js&#39;;

const sbName = &#39;my-sb-name&#39;;
const topicName = &#39;my-topic-name&#39;;
const sharedAccessKey = &#39;my-shared-access-key&#39;;
const sharedAccessName = &#39;RootManagerSharedAccessKey&#39;;
const expiry = Math.floor(Date.now() / 1000) + 10000;
const baseUrl = `https://${sbName}.servicebus.windows.net`;
const url = `${baseUrl}/${topicName}`;
const toSign = `${url}\n${expiry.toString()}`;
const signature = SHA256(toSign).toString();
const encodedSignature = encodeURIComponent(signature);
const authFormat = `SharedAccessSignature sig={0}&amp;se={1}&amp;skn={2}$sr={3}`;
const auth = authFormat
  .replace(&#39;{0}&#39;, encodedSignature)
  .replace(&#39;{1}&#39;, expiry.toString())
  .replace(&#39;{2}&#39;, sharedAccessName)
  .replace(&#39;{3}&#39;, url);

console.log(auth);

const headers = {
  Authorization: auth,
  &#39;Content-Type&#39;: &#39;application/json&#39;,
};

const getDetails = async () =&gt; {
  try {
    const response = await axios.get(url, { headers });
    console.log(&#39;Queue Details:&#39;, response.data);
    // Process the response or update your UI with the retrieved queue details
  } catch (error) {
    console.error(&#39;Error retrieving queue details:&#39;, error);
  }
};
// Call the function to get queue details
export default getDetails;

<!-- end snippet -->

which gives error: 401 unauthorized

答案1

得分: 1

> 我目前遇到了401未经授权的错误

这是因为您提供了不正确的授权密钥。
您可以使用以下代码生成SAS令牌,然后将其用于Authorization头部以获取主题数据。

生成SAS令牌的代码

const crypto = require('crypto');
const querystring = require('querystring');
const sb_name = 'afreen-serviceBus-01';
const topic = 'demotopic';
const url = `https://${sb_name}.servicebus.windows.net/${topic}`;
const sas_value = 'xxxxxxxxxxx'; // 您的共享访问密钥
const sas_name = 'RootManageSharedAccessKey'; // 您的共享访问规则名称
const expiry = Math.floor(Date.now() / 1000) + 10000;
const to_sign = `${url}\n${expiry}`;
const signature = crypto.createHmac('sha256', sas_value)
  .update(to_sign)
  .digest('base64');
const encodedSignature = querystring.escape(signature);
const auth_format = 'SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}';
const auth = auth_format.replace('{0}', encodedSignature)
  .replace('{1}', expiry)
  .replace('{2}', sas_name)
  .replace('{3}', url);
console.log(auth);

输出

如何从前端接收来自Azure服务总线主题的通知?

请参考微软文档

Authorization: SharedAccessSignature ${access key}的位置使用上面生成的SharedAccessSignature密钥。

除了访问密钥之外,我使用了您的代码而没有进行任何修改。我使用了上面生成的密钥,得到了预期的结果。

如何从前端接收来自Azure服务总线主题的通知?

英文:

> I am currently getting 401 unauthorized error

It is because you are providing incorrect authorization key.
You can use the below code to generate the SAS token and then you can use it in the Authorization header to get the topic data.

Code to generate SAS token

const  crypto  =  require(&#39;crypto&#39;);
const  querystring  =  require(&#39;querystring&#39;);
const  sb_name  =  &#39;afreen-serviceBus-01&#39;;
const  topic  =  &#39;demotopic&#39;;
const  url  =  `https://${sb_name}.servicebus.windows.net/${topic}`;
const  sas_value  =  &#39;xxxxxxxxxxx&#39;; // your shared access key
const  sas_name  =  &#39;RootManageSharedAccessKey&#39;; // your shared access rule name
const  expiry  =  Math.floor(Date.now() /  1000) +  10000;
const  to_sign  =  `${url}\n${expiry}`;
const  signature  =  crypto.createHmac(&#39;sha256&#39;, sas_value)
.update(to_sign)
.digest(&#39;base64&#39;);
const  encodedSignature  =  querystring.escape(signature);
const  auth_format  =  &#39;SharedAccessSignature sig={0}&amp;se={1}&amp;skn={2}&amp;sr={3}&#39;;
const  auth  =  auth_format.replace(&#39;{0}&#39;, encodedSignature)
.replace(&#39;{1}&#39;, expiry)
.replace(&#39;{2}&#39;, sas_name)
.replace(&#39;{3}&#39;, url);
console.log(auth);

Output

如何从前端接收来自Azure服务总线主题的通知?

Please refer ms docs

Use the above generated SharedAccessSignature key in the place of access key of Authorization: SharedAccessSignature ${access key}.

I have used your code without any modification except the access key. I have used the above generated key which gave me the expected result.

如何从前端接收来自Azure服务总线主题的通知?

答案2

得分: 0

我使用了 @azure/service-bus 并按照官方文档的建议配置了依赖项,它正常工作。

我在我的 react 18 应用中使用了 react-scripts。因此,为了将推荐的配置与 react-scripts 合并,我将 @craco/craco 安装为开发依赖项。

在我的 craco.config.js 文件中添加了以下配置:

const webpack = require('webpack');

module.exports = {
  webpack: {
    configure: (webpackConfig) => {
      webpackConfig.resolve.fallback = {
        ...webpackConfig.resolve.fallback,
        os: require.resolve('os-browserify/browser'),
        path: require.resolve('path-browserify'),
        buffer: require.resolve('buffer/'),
        process: require.resolve('process/browser'),
      }
      webpackConfig.plugins.push(
        new webpack.ProvidePlugin({
          Buffer: ['buffer', 'Buffer'],
          process: 'process/browser'
        })
      );
      return webpackConfig;
    }
  }
}

在我的 package.json 文件中的 "scripts" 部分,将 react-scripts start 替换为 craco start

"scripts": {
  "start": "craco start",
  "build": "craco build",
  // ...
}

在我的 getServiceTopicMessage.js 文件中:

import { ServiceBusClient } from '@azure/service-bus';

async function getServiceBusTopicMessage() {
  const connectionString = '你的连接字符串';
  const topicName = '你的主题名称';
  const subscriptionName = '你的订阅名称';
  
  const serviceBusClient = new ServiceBusClient(connectionString);
  const receiver = serviceBusClient.createReceiver(topicName, subscriptionName);
  
  try {
    console.log('等待消息...');
    while(true) {
      const messages = await receiver.receiveMessages(1, {maxWaitTimeInMs: 5000});
      if(messages.length > 0) {
        console.log(messages[0].body);
        await receiver.completeMessage(messages[0]);
      }
    }
  } catch (error) {
    console.error(error);
  } finally {
    await receiver.close();
    await serviceBusClient.close();
  }
}

export default getServiceBusTopicMessage;

只需在所需的页面中导入该函数并调用,它就会正常工作。

英文:

I used @azure/service-bus and configured the dependencies as suggested in their official documentaion and it worked.

Iam using react-scripts for my react 18 app. So., inorder to merge the recommended config with react-scripts., I installed @craco/craco as dev dependency.

in my craco.config.js added following configuration:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const webpack = require(&#39;webpack&#39;);

module.exports = {
  webpack: {
    configure: (webpackConfig) =&gt; {
      webpackConfig.resolve.fallback = {
        ...webpackConfig.resolve.fallback,
        os: require.resolve(&#39;os-browserify/browser&#39;),
        path: require.resolve(&#39;path-browserify&#39;),
        buffer: require.resolve(&#39;buffer/&#39;),
        process: require.resolve(&#39;process/browser&#39;),
      }
      webpackConfig.plugins.push(
        new webpack.ProvidePlugin({
          Buffer: [&#39;buffer&#39;, &#39;Buffer&#39;],
          process: &#39;process/browser&#39;
        })
      );
      return webpackConfig;
    }
  }
}

<!-- end snippet -->

and in my "scripts" in package.json., replaced react-scripts start to craco start as below:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

&quot;start&quot;: &quot;craco start&quot;,
&quot;build&quot;: &quot;craco build&quot;,

<!-- end snippet -->

in my getServiceTopicMessage.js

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

import { ServiceBusClient } from &#39;@azure/service-bus&#39;;

async function getServiceBusTopicMessage() {
  const connectionString = &#39;your connection string&#39;;
  const topicName = &#39;your topic name&#39;;
  const subscriptionName = &#39;your subscription name&#39;;
  
  const serviceBusClient = new ServiceBusClient(connectionString);
  const receiver = serviceBusClient.createReceiver(topicName, subscriptionName);
  
  try {
    console.log(&#39;waiting for messages...&#39;);
    while(true) {
      const messages = await receiver.receiveMessages(1, {maxWaitTimeInMs: 5000});
    if(messages.length &gt; 0) {
      console.log(messages[0].body);
      await receiver.completeMessage(messages[0]);
    }
  }
  } catch (error) {
    console.error(error);
  } finally {
    await receiver.close();
    await serviceBusClient.close();
  }
}
export default getServiceBusTopicMessage;

<!-- end snippet -->

and just import the function in your required page and call. it works

huangapple
  • 本文由 发表于 2023年7月11日 14:58:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76659393.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定