LoginSignup
272
282

More than 5 years have passed since last update.

Vue.js 2.0 でログイン (vue-router で認証が必要な URL を定義)

Last updated at Posted at 2016-11-20

認証が必要な URL にアクセスした時に、まだログインしていない場合にはログインボタンを表示します。

作成にあたって以下の知識が必要になるので、順に試していきます。

  • コンポーネント
  • vue-router
  • ルートメタフィールド、ナビゲーションガード

Playground として http://codepen.io を使用します。できあがったコードは http://codepen.io/takatama/pen/zoNeWP です。
Vue.js 2.0.7 と vue-router 2.0.2 で動作を確認しました。

なお、Vue.jsについて体系的に学ぶには「Vue.js入門」が超絶オススメです。ログイン、ログアウトについても丁寧に解説されています。

コンポーネント

ドキュメントは https://vuejs.org/v2/guide/components.html です。

User コンポーネントを作ります。プロパティとして name を持ちます。

codepen で Settings > JavaScript > Add External JavaScript で https://unpkg.com/vue/dist/vue.js と入力し、Save & Change ボタンを押します。

HTML:

<div id="app">
  <About />
</div>

JavaScript:

var About = { template: '<h1>About</h1>' };

var app = new Vue({
  el: '#app',
  components: {
    'About': About
  },
});

vue-router

ドキュメントは http://router.vuejs.org/ja/essentials/getting-started.html です。

Dashboard コンポーネントを追加します。/about に About コンポーネント、/dashboard に Dashboard コンポーネントをそれぞれ登録します。

Settings > JavaScript > Add External JavaScript で
https://unpkg.com/vue-router/dist/vue-router.js を追加入力し、Save & Change ボタンを押します。

HTML:

<div id="app">
  <p>
    <router-link to="/about">About</router-link>
    <router-link to="/dashboard">Dashboard</router-link>
  </p>
  <router-view></router-view>
</div>

JavaScript:

var About = { template: '<h1>About</h1>' };
var Dashboard = { template: '<h1>Dashboard</h1>' };

var routes = [
  { path: '/about', component: About },
  { path: '/dashboard', component: Dashboard }
];

var router = new VueRouter({
  routes
});

var app = new Vue({
  el: '#app',
  router
});

<router-view>\ に選択されたコンポーネントが表示されます。

ログインページ

ドキュメントは

です。

/about は認証不要、/dashboard は認証が必要な URL とします。認証が必要な URL にアクセスし、かつ、まだログインしていない場合にログインボタンを表示します。

HTML (変更なし) :

<div id="app">
  <p>
    <router-link to="/about">About</router-link>
    <router-link to="/dashboard">Dashboard</router-link>
  </p>
  <router-view></router-view>
</div>

JavaScript:

認証処理をする Auth と、Login コンポーネントを追加する。/login に Login コンポーネントを登録します。

/dashboard がログインを要することを meta で定義します。ナビゲーションガード router.beforeEach を使って、ログインが必要で、かつ、未ログインの場合に /login にリダイレクトします。

/login にリダイレクトする際、もともとアクセスしようとしていた URL を query パラメーターに付与します( /login?redirect=/dashbaord )。

var About = { template: '<h1>About</div>' };
var Dashboard = { template: '<h1>Dashboard</h1>' };

var Auth = {
  loggedIn: false,
  login: function() { this.loggedIn = true },
  logout: function() { this.loggedIn = false }  
};

var Login = {
  template: '<input type="submit" value="Login" v-on:click="login">',
  methods: {
    login: function() {
      Auth.login();
      router.push(this.$route.query.redirect);
    }
  }
};

var routes = [
  { path: '/about', component: About },
  { path: '/dashboard', component: Dashboard, meta: { requiresAuth: true }},
  { path: '/login', component: Login }
];

var router = new VueRouter({
  routes
});

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth) && !Auth.loggedIn) {
    next({ path: '/login', query: { redirect: to.fullPath }});
  } else {
    next();
  }
});

var app = new Vue({
  el: '#app',
  router
});

ログアウト

Dashboard コンポーネントに /logout へのリンクを追加します。

JavaScript (主な差分のみ):

var Dashboard = {
  template: '<div><h1>Dashboard</h1><router-link to="/logout">Logout</router-link></div>'
};
var Logout = {
  template: '<input type="submit" value="Logout" v-on:click="logout">',
  methods: {
    logout: function() {
      Auth.logout();
      router.push('/');
    }
  }
};
var routes = [
  { path: '/about', component: About },
  { path: '/dashboard', component: Dashboard, meta: { requiresAuth: true }},
  { path: '/login', component: Login },
  { path: '/logout', component: Logout }
];

補足 (デフォルトで認証を有効にする)

ほとんどの URL で認証を必要とするのであれば、デフォルトで認証を有効にして、認証が不要な URL にだけ isPublic: true を指定する方が安全です。認証が必要な URL に meta を定義し忘れ、誤って一般公開してしまうミスを防ぐことができます。

// 全てのURLで認証を必要とする。isPubilc: true の場合だけ認証不要。
var routes = [
  { path: '/about', component: About, meta: { isPublic: true } },
  { path: '/dashboard', component: Dashboard}, // 認証を必要とする
  { path: '/login', component: Login, meta: { isPublic: true } }
];

var router = new VueRouter({
  routes
});

router.beforeEach((to, from, next) => {
  // isPublic でない場合(=認証が必要な場合)、かつ、ログインしていない場合
  if (to.matched.some(record => !record.meta.isPublic) && !Auth.loggedIn) {
    next({ path: '/login', query: { redirect: to.fullPath }});
  } else {
    next();
  }
});
272
282
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
272
282