🦐

AmplifyのJavascript SDKでCognito認証からデータ取得まで

2021/02/05に公開

はじめに

この回でCognito, API Gateway, Lambda, DynamoDBあたりが動いて、この回でAmplifyでHosting作るところまでやったので、今回はAmplify Javascript SDKでフロントをかいてみる回

Cognito認証JWTトークン取るトークンもってAPIでデータを取得 っていうのをやってみる

スクリーンショット

画面はシンプルにこんな感じのを作ってみた。左がログインフォームで右がバックエンドからのレスポンス。

コード

index.html
<!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 から値を取り出しているので長くなっていてちょっといけてない感じがするが、どうするのが普通なんでしょ?

app.js
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 界隈の知識不足で引っかかったことの方が多かった。webpackbunlde したら関数がプライベートになって、htmlから呼び出せない... とか、Promise が... とか、async/await が... とか、そういうやつ。勉強になりました

シリーズ

Discussion