AmplifyのJavascript SDKでCognito認証からデータ取得まで
はじめに
この回でCognito, API Gateway, Lambda, DynamoDBあたりが動いて、この回でAmplifyでHosting作るところまでやったので、今回はAmplify Javascript SDKでフロントをかいてみる回
Cognito認証
→JWTトークン取る
→トークンもってAPIでデータを取得
っていうのをやってみる
スクリーンショット
画面はシンプルにこんな感じのを作ってみた。左がログインフォームで右がバックエンドからのレスポンス。
コード
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
<script src="main.bundle.js"></script>
<script>
function getName() { return document.getElementById('Username').value }
function getPass() { return document.getElementById('Password').value }
function putRes(res) {
document.getElementById('Result').innerHTML = JSON.stringify(res, null, 2);
}
</script>
<style>
pre {
overflow: auto;
white-space: pre-wrap;
word-wrap: break-word;
background: dimgray;
color: white;
border-radius: 5px;
padding: 10px;
margin-top: 0px;
}
</style>
</head>
<body>
<div>
<div class="container">
<div class="row">
<div class="one-third column">
<form>
<label for="Username">Username</label>
<input class="u-full-width" type="text" placeholder="Username" id="Username">
<label for="Username">Password</label>
<input class="u-full-width" type="password" placeholder="Password" id="Password">
<div class="row">
<input class="one-half column button-primary" type="button" value="login" onclick="signIn(getName(), getPass()).then(r => putRes(r)).catch(e => putRes(e))">
<input class="one-half column" type="button" value="logout" onclick="console.log(signOut())">
</div>
<div class="row">
<input class="u-full-width" type="button" value="getData" onclick="getData().then(r => putRes(r)).catch(e => putRes(e))">
</div>
</form>
</div>
<div class="two-thirds column">
<label>Output</label>
<pre id="Result"></pre>
</div>
</div>
</div>
</div>
</body>
</html>
onclick()
の中で Promise
から値を取り出しているので長くなっていてちょっといけてない感じがするが、どうするのが普通なんでしょ?
import Amplify, { API } from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
const signIn = async (username, password) => {
try {
return await Amplify.Auth.signIn(username, password)
} catch (error) {
return error
}
}
const signOut = () => {
try {
return Amplify.Auth.signOut();
} catch (error) {
return error
}
}
Amplify.configure({
API: {
endpoints: [
{
name: "your-api-name",
endpoint: "https://your-api-id.execute-api.us-east-2.amazonaws.com/dev_1",
}
]
}
});
const getData = async () => {
const apiName = 'your-api-name';
const path = '/projects';
const myInit = {
headers: {
Authorization: `Bearer ${(await Amplify.Auth.currentSession()).getIdToken().getJwtToken()}`,
},
};
return await API.get(apiName, path, myInit);
}
window.getData = getData;
window.signIn = signIn;
window.signOut = signOut;
app.js
は公式のサンプルにパラメータいれただけですが、とりあえずこれだけで動きます。なかなかわかりやすくていい感じです。
だいたい使い方がわかってきました。
認証情報をインポート
お気づきの通り、上のコードにはCognito周りのパラメータがない。では、Amplify SDKはどうやってCognitoのプール情報を得ているのかというと、事前に以下のようにしてインポートする
amplify import auth
対話式にいろいろ聞かれますが、基本的に今回のように認証だけであれば(認可をしないのであれば)、Cognito User Pool only
を選んでおけばいいです。amplify push
を忘れずに
これにより、プロジェクトフォルダのsrc/aws-exports.js
に認証周りの情報が書き込まれているはず
余談
今回は、Amplify SDK そのものよりは、Javascript 界隈の知識不足で引っかかったことの方が多かった。webpack
で bunlde
したら関数がプライベートになって、htmlから呼び出せない... とか、Promise
が... とか、async/await
が... とか、そういうやつ。勉強になりました
Discussion