この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
IoT 事業部の平内(SIN)です。
AWS Amplify(以下、Amplify)で提供されるJavaScriptライブラリ(PubSubカテゴリ)を使用すると、ブラウザからAWS IoT CoreのメッセージブローカーへのPublish/Subscribeが、簡単に実装できます。
https://docs.amplify.aws/lib/pubsub/getting-started/q/platform/js/
上記のドキュメントでは、Cognitoで認証した状態での利用方法が説明されていますが、個人的に、ちょっと理解が難しかったので、今回、未認証での利用から、認証済み利用への移行という形で、実装方法を確認してみました。(既に、有用なコンテンツがある中、本記事が、個人的な備忘録となっていることをお許しください)
下記は、最終的に認証済みのブラウザと、AWS IoTコンソールのテスト画面でPublish及び、Subscribeの動作を確認している様子です。
2 Authカテゴリの追加
サンプルに使用したプラットフォームは、Vue 3です。
% vue create pub_sub_sample
>Default (Vue 3) ([Vue 3] babel, eslint)
% cd pub_sub_sample
% amplify init
PubSubのライブラリを使用するためには、AWS IoTへのアクセス権付与のため、Authの追加が必須です。
Amplify CLIによる手順は以下の通りとなります。
% amplify add auth
> Default configuration
> Username
% amplify push
% amplify status
Current Environment: dev
┌──────────┬──────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin │
├──────────┼──────────────────────┼───────────┼───────────────────┤
│ Auth │ pubsubsampleaf4356ed │ No Change │ awscloudformation │
└──────────┴──────────────────────┴───────────┴───────────────────┘
また、ここでUIコンポーネントのインストールと、リソース情報の受け渡し設定を完了させておきます。
% yarn add aws-amplify @aws-amplify/ui-components
src/main.js
import { createApp } from 'vue'
import App from './App.vue'
// 追加
import Amplify from 'aws-amplify';
import aws_exports from './aws-exports';
import {
applyPolyfills,
defineCustomElements,
} from '@aws-amplify/ui-components/loader';
Amplify.configure(aws_exports);
applyPolyfills().then(() => {
defineCustomElements(window);
});
createApp(App).mount('#app')
3 未認証での利用
(1) ポリシー作成
最初に、my_client_idで接続し、my_topicにPubulish/Subscribeする事ができるポリシーを作成します。
pub_sub_sample_policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": [
"arn:aws:iot:ap-northeast-1:*:client/my_client_id"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Receive"
],
"Resource": [
"arn:aws:iot:ap-northeast-1:*:topic/my_topic"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Subscribe"
],
"Resource": [
"arn:aws:iot:ap-northeast-1:*:topicfilter/my_topic"
]
}
]
}
(2) 未認証アクセスの有効化
Anplifyのコンソールから、セットアップされたCognitoのコンソールを開き、プールIDの編集から、 「認証されていない ID に対してアクセスを有効にする」 にチェックを入れます。
(3) Role(未認証)へのポリシー追加
続いて、未認証で使用されるロールに、先ぽどのポリシー(pub_sub_sample_policy)を追加します。
(4) 動作確認
App.vueを以下のように編集し、PubSub.publish() 及び、PubSub.subscribe() を実装します。
App.vue
<template>
<h1>Pub/Sub</h1>
<input type="text" v-model="message" placeholder="メッセージ">
<button v-on:click="publish">Publish</button>
<div v-for="item in items" :key="item.message">
<p>{{ item.message }}</p>
</div>
</template>
<script>
import Amplify,{ PubSub } from 'aws-amplify';
import { AWSIoTProvider } from '@aws-amplify/pubsub';
const AWS_REGION = 'ap-northeast-1';
const ENDPOINT = 'xxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com';
const TOPIC = 'my_topic';
Amplify.addPluggable(new AWSIoTProvider({
aws_pubsub_region: AWS_REGION,
aws_pubsub_endpoint: `wss://${ENDPOINT}/mqtt`,
clientId: 'my_client_id'
}));
export default {
name: 'App',
async created() {
this.subscribe()
},
data() {
return {
items: []
}
},
methods: {
async subscribe() {
PubSub.subscribe(TOPIC).subscribe({
next: data => {
console.log(data.value.message)
this.items = [...this.items, {'message': data.value.message}];
},
error: error => console.error(error),
close: () => console.log('Done'),
});
},
async publish() {
const { message } = this;
if (!message) return;
await PubSub.publish(TOPIC, { message: message });
this.message = '';
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
input{
width: 300px;
height:30px;
}
button {
margin:10px;
width: 70px;
height: 38px;
border: solid 1px silver;
border-radius: 0.5rem 0.5rem;
}
button:active{
padding-top:6px;
padding-bottom:4px;
border:1px solid #334c66;
background-color:#69c;
color:#ffffff;
}
</style>
Iot Core コンソールのテストクライアントで、メッセージのやり取りを確認できます。ここで分かる通り、未認証で利用する場合、当該ロールに権限を付与するだけで利用できることになります。
(5) 未認証の無効化
未認証でのPublish及び、Subscribeが確認できましたが、続いて、認証時の動作を確認するために、いったん、未認証によるアクセスを無効化します。
無効化した時点で、Subscribe、Publishは、共にエラーとなって接続できなくなる事が確認できます。
4 認証有りでの利用
(1) 認証画面
認証を有効にするために、App.vueのtemplateに、Amplify Framework UIコンポーネント( <amplify-authenticator> 及び、<amplify-sign-out> )を追加します。
src/App.vue
<template>
<amplify-authenticator>
<amplify-sign-out></amplify-sign-out>
<h1>Pub/Sub</h1>
<input type="text" v-model="message" placeholder="メッセージ">
<button v-on:click="publish">Publish</button>
<div v-for="item in items" :key="item.message">
<p>{{ item.message }}</p>
</div>
</amplify-authenticator>
</template>
追加すると、認証されていない場合の画面は、下記のようになります。
Create accountでアカウントを作成し、ログインした状態(認証済み)になると、下記のような画面となります。
(2) Role(認証済み)へのポリシー追加
認証済みの際に有効となるロールに、AWSIoTDataAccess 及び、AWSIoTConfigAccess を追加します。
ここでは、詳細なアクセス制御が行われていませんが、この後で設定する個々のアカウントに対するポリシーで設定することが可能です。
(3) ポリシー作成
今回作成するポリシーは、IoT Coreのポシリーです。内容は、先にIAMで作成したものと同じとなっています。 (名前は、pub_sub_sample_policyとしました)
(4) IDENTITY_IDへのポリシー追加
上記で作成したポリシーは、IDENTITY_IDに紐付けます。
この作業は、コンソールからは行えないため、AWS CLIからの作業になります。
% aws iot attach-policy --policy-name pub_sub_sample_policy --target '<YOUR_COGNITO_IDENTITY_ID>'
なお、IDENTITY_IDは、CognitoのコンソールのIDブラウザで確認できます。現在、1つのアカウントを作成してログインしたので、1つだけ表示されている事が確認できます。
紐付けが完了すると、ポリシーの「証明書」一覧に、表示されます。
(5) 動作確認
ここまでの作業が完了すると、ログインすることで、Pub/Subがエラーなく動作することを確認できます。
5 最後に
今回は、Amplifyによる、PubSubライブラリの利用について確認してみました。個人的には、アカウント単位のIDENTITY_IDにポリシーを紐づけるあたりの作業が、ちょっと理解に苦労しました。