AWS Amplifyを使ってサインインを実装する-2

Authenticationを利用してサインアップを実装していきます。
前回のAWS Amplifyを使ってサインインを実装する-1 に追加していきます。

環境等

項目 バージョン
node v10.15.3
npm 6.4.1
@aws-amplify/cli 1.6.11
aws-amplify 1.1.28
aws-amplify-vue 0.2.11
vuesax 3.8.65
material-icons 0.3.1

実装

コードは最後にまとめて記載しています。

Sign up

views/Signup.vueを作成します。
Auth.signUpを利用して、Sign upを行います。

Sign upを行うと、検証コードが記入したメールアドレスに送信されます。
検証コードによる確認のため、views/ConfirmSignup.vueに遷移するようにしています。

検証コードによる確認

views/ConfirmSignup.vueを作成します。
Auth.confirmSignUpを利用して、検証コードによる登録確認を行います。

登録確認が完了すると、views/Signin.vueに遷移するようにしています。

ルート定義の追加と認証済みチェック

router.jsを修正します。
上記で追加したページへの遷移と、認証済みである事を要求するページとして、views/About.vueを指定しています。
これは、vue cliで作成されたものですので、記載しません。

認証済みチェックには、Auth.currentAuthenticatedUserを利用しています。

Sign upへのリンク追加

App.vueを修正し、リンクを生成します。

Sign upリンクを追加しています。

Sign in後の遷移

Signup.vueはSign inが完了すると、abaout.vueに遷移するようにしています。

コード

<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/signin">Sign in</router-link> |
<router-link to="/signup">Sign up</router-link>
</div>
<router-view />
</div>
</template>
<style lang="scss">
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
color: #2c3e50;
}
#nav {
text-align: center;
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>

view raw
App.vue
hosted with ❤ by GitHub

<template>
<vs-row vs-justify="center">
<vs-col type="flex" vs-lg="6" vs-xs="10">
<vs-card fixedHeight>
<div slot="header">
<h3>
Confirm Sign up
</h3>
</div>
<div class="centerx">
<vs-row>
<vs-col vs-w="12">
<vs-input
type="text"
label-placeholder="Verification Code"
v-model="userInfo.verificationCode"
class="input"
size="large"
/>
</vs-col>
</vs-row>
<vs-row>
<vs-col vs-w="12">
<vs-button class="signup" @click="signup">Verify</vs-button>
</vs-col>
</vs-row>
<div slot="footer" class="error-message">
{{ this.errorMessage }}
</div>
</div>
</vs-card>
</vs-col>
</vs-row>
</template>
<script>
export default {
name: "ConfirmSignup",
data() {
return {
userInfo: {
verificationCode: ""
},
errorMessage: ""
};
},
methods: {
async signup() {
if (!this.validate()) {
return;
}
try {
await this.$Amplify.Auth.confirmSignUp(
this.$route.params.email,
this.userInfo.verificationCode
);
this.$router.push("/signin");
} catch {
this.errorMessage = "サインアップできませんでした";
}
},
validate() {
if (!this.userInfo.verificationCode) {
this.errorMessage = "Verify Codeが入力されていません。";
return;
}
this.errorMessage = "";
return true;
}
}
};
</script>
<style lang="sass" scoped>
.centerx
display: flex
align-items: center
justify-content: center
flex-wrap: wrap
.input
width:100%
padding: 16px 64px
.signup
width: calc(100% 64px * 2)
padding: 16px 0
margin: 32px 64px 0
.error-message
color: #FF0000
margin: 32px 64px
</style>

view raw
ConfirmSignup.vue
hosted with ❤ by GitHub

import Vue from "vue";
import Router from "vue-router";
import { Auth } from "aws-amplify";
import Home from "./views/Home.vue";
Vue.use(Router);
async function requireAuth(to, from, next) {
try {
await Auth.currentAuthenticatedUser();
next();
} catch {
next({
name: "signin"
});
}
}
export default new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "home",
component: Home
},
{
path: "/about",
name: "about",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "./views/About.vue"),
beforeEnter: requireAuth
},
{
path: "/signin",
name: "signin",
component: () => import("./views/Signin.vue")
},
{
path: "/signup",
name: "signup",
component: () => import("./views/Signup.vue")
},
{
path: "/confirm-signup",
name: "confirm-signup",
component: () => import("./views/ConfirmSignup.vue")
},
{
path: "/signout",
name: "signout",
async beforeEnter(to, from, next) {
await this.$Amplify.Auth.signOut();
next("signin");
}
}
]
});

view raw
router.js
hosted with ❤ by GitHub

<template>
<vs-row vs-justify="center">
<vs-col type="flex" vs-lg="6" vs-xs="10">
<vs-card fixedHeight>
<div slot="header">
<h3>
Sign in
</h3>
</div>
<div class="centerx">
<vs-row>
<vs-col vs-w="12">
<vs-input
type="email"
label-placeholder="email"
v-model="userInfo.email"
class="input"
size="large"
/>
</vs-col>
</vs-row>
<vs-row>
<vs-col vs-w="12">
<vs-input
type="password"
label-placeholder="Password"
v-model="userInfo.password"
class="input"
size="large"
/>
</vs-col>
</vs-row>
<vs-row>
<vs-col vs-w="12">
<vs-button class="signin" @click="signIn">Sign in</vs-button>
</vs-col>
</vs-row>
<div slot="footer" class="error-message">
{{ this.errorMessage }}
</div>
</div>
</vs-card>
</vs-col>
</vs-row>
</template>
<script>
export default {
name: "Signin",
data() {
return {
userInfo: {
email: "",
password: ""
},
errorMessage: ""
};
},
methods: {
async signIn() {
try {
await this.$Amplify.Auth.signIn(
this.userInfo.email,
this.userInfo.password
);
this.$router.push("/about");
} catch {
this.errorMessage = "ログインできませんでした";
}
}
}
};
</script>
<style lang="sass" scoped>
.centerx
display: flex
align-items: center
justify-content: center
flex-wrap: wrap
.input
width:100%
padding: 16px 64px
.signin
width: calc(100% 64px * 2)
padding: 16px 0
margin: 32px 64px 0
.error-message
color: #FF0000
margin: 32px 64px
</style>

view raw
Signin.vue
hosted with ❤ by GitHub

<template>
<vs-row vs-justify="center">
<vs-col type="flex" vs-lg="6" vs-xs="10">
<vs-card fixedHeight>
<div slot="header">
<h3>
Sign up
</h3>
</div>
<div class="centerx">
<vs-row>
<vs-col vs-w="12">
<vs-input
type="email"
label-placeholder="email"
v-model="userInfo.email"
class="input"
size="large"
/>
</vs-col>
</vs-row>
<vs-row>
<vs-col vs-w="12">
<vs-input
type="password"
label-placeholder="Password"
v-model="userInfo.password"
class="input"
size="large"
/>
</vs-col>
</vs-row>
<vs-row>
<vs-col vs-w="12">
<vs-input
type="password"
label-placeholder="Confirm Password"
v-model="userInfo.confirmPassword"
class="input"
size="large"
/>
</vs-col>
</vs-row>
<vs-row>
<vs-col vs-w="12">
<vs-button class="signup" @click="signup">Sign up</vs-button>
</vs-col>
</vs-row>
<div slot="footer" class="error-message">
{{ this.errorMessage }}
</div>
</div>
</vs-card>
</vs-col>
</vs-row>
</template>
<script>
export default {
name: "Signup",
data() {
return {
userInfo: {
email: "",
password: "",
confirmPassword: ""
},
errorMessage: ""
};
},
methods: {
async signup() {
if (!this.validate()) {
return;
}
try {
await this.$Amplify.Auth.signUp(
this.userInfo.email,
this.userInfo.password
);
this.$router.push({
name: "confirm-signup",
params: { email: this.userInfo.email }
});
} catch {
this.errorMessage = "サインアップできませんでした";
}
},
validate() {
if (!this.userInfo.email) {
this.errorMessage = "emailが入力されていません。";
return;
}
if (!this.userInfo.password) {
this.errorMessage = "passwordを入力してください。";
return;
}
if (this.userInfo.password !== this.userInfo.confirmPassword) {
this.errorMessage = "パスワードが一致しません。";
return false;
}
this.errorMessage = "";
return true;
}
}
};
</script>
<style lang="sass" scoped>
.centerx
display: flex
align-items: center
justify-content: center
flex-wrap: wrap
.input
width:100%
padding: 16px 64px
.signup
width: calc(100% 64px * 2)
padding: 16px 0
margin: 32px 64px 0
.error-message
color: #FF0000
margin: 32px 64px
</style>

view raw
Signup.vue
hosted with ❤ by GitHub

スポンサーリンク
  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存
スポンサーリンク

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA