Vue.jsのrouter機能を使ってユーザ認証を実装してみます。
環境
カテゴリ | バージョンなど |
---|---|
os | windows 10 home 64bit |
vue | 2.4.2 |
vue-router | 2.7.0 |
全体のhtml
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue.js SPAのサンプルアプリケーション</title>
<style>
.container {
width:100%;
height:100%;
display:flex;
justify-content: center;
align-items: center;
}
.content {
min-width: 33%;
min-height: 33%;
}
.error {
color: red;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<div class="content">
<router-view></router-view>
</div>
</div>
</div>
<script src="https://unpkg.com/vue@2.4.2/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-router@2.7.0/dist/vue-router.min.js"></script>
<script>
//認証情報はこのオブジェクトで管理する。
var Auth = {
loggedIn: false,
login: function(email, pass) {
//TODO: ここはサーバで認証処理(login)を実行する。
(email == "vue@example.com" && pass == "vue" )?this.loggedIn = true:this.loggedIn = false;
//TODO: サーバから取得したtokenをlocalstrageに保存するように変更が必要。
localStorage.token = Math.random().toString(36).substring(7)
return this.loggedIn;
},
logout: function() {
//TODO: ここはサーバで認証処理(logout)を実行する。
this.loggedIn = false
delete localStorage.token
}
};
//トップメニューコンポーネント
var Top = {
template: '<div>'
+'<h2>Top</h2>'
+'<div style="width:600px;text-align:right;">'
+'<router-link to="/logout">Logout</router-link>'
+'</div>'
+'<ul>'
+'<li>'
+'メニュー1'
+'</li>'
+'<li>'
+'メニュー2'
+'</li>'
+'</ul>'
+'</div>'
};
//ログインコンポーネント
var Login = {
template: ''
+'<div>'
+' <h2>Login</h2>'
+' <p v-if="$route.query.redirect">'
+' ログインしてください'
+' </p>'
+' <p v-if="error" class="error">ログインに失敗しました</p>'
+' <form @submit.prevent="login">'
+' <table>'
+' <tr><td>E-Mail:</td><td><input v-model="email" placeholder="email"></td></tr>'
+' <tr><td>password:</td><td><input v-model="pass" placeholder="password" type="password"></td></tr>'
+' </table>'
+' <input type="submit" value="Login" v-on:click="login">'
+' </form>'
+'</div>',
data: function () {
return {
email: 'vue@example.com',
pass: '',
error: false
}
},
methods: {
login: function() {
this.error = !Auth.login(this.email, this.pass);
if (!this.error) {
router.push(this.$route.query.redirect);
};
}
}
};
//ログアウトコンポーネント
//画面描画時に、ログアウトメソッドが呼び出され、ログアウトする。
var Logout = {
template: '<input type="submit" value="Logout" v-on:click="logout">',
methods: {
logout: function() {
Auth.logout();
router.push('/top');
}
},
created: function(){
this.logout()
}
};
//ルーター定義
var routes = [
{ path: '/top', component: Top, meta: { requiresAuth: true }},
{ path: '/login', component: Login },
{ path: '/logout', component: Logout },
{
// 定義されていないパスへの対応。トップページへリダイレクトする。
path: '*',
redirect: '/top'
}
];
//ルーター
var router = new VueRouter({
"routes": routes
});
//認証がない場合は、ログインページに遷移する。
router.beforeEach(function (to, from, next) {
if (to.matched.some(function (record) {
return record.meta.requiresAuth;
}) && !Auth.loggedIn) {
next({ path: '/login', query: { redirect: to.fullPath } });
} else {
next();
}
});
var app = new Vue({
el: '#app',
"router": router
});
</script>
</body>
</html>
Python+Djangoやphp+laravelなどのフルスタックだと認証機能があるのですが、そうではない環境では、vue-routerを使うというのも一つの手段として有効ではないかと思います。