LoginSignup
0
1

More than 1 year has passed since last update.

【備忘録】Laravel + Vueで管理者認証機能を実装する

Last updated at Posted at 2021-04-11

バージョン確認

PHP7.3
Laravel7.30
vue2.6.12

Dockerを使ってローカル環境構築済み
一般ユーザーの認証機能は実装済み

手順

  • 一般ユーザーはusersテーブル、管理者画面はadminsテーブルを使う
  • 管理者はlogin_idpasswordでログイン、ログアウトできるところまでを実装
  • 便宜上管理者の新規登録機能も実装し、実務ではマスター管理などに応用する
  • app.tsに、常に管理者の認証状態をvuexで保持するよう記述する
  • コンポーネント化とcssによるスタイリングは割愛

Laravel側の実装

/var/www/laravel
$ php artisan make:model Models/Admin -m
database/migrations/2021_03_31_120856_create_admins_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateAdminsTable extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('admins', function (Blueprint $table) {
      $table->id();
      $table->string('name');
      $table->string('login_id');
      $table->string('email');
      $table->timestamp('email_verified_at')->nullable();
      $table->string('password');
      $table->rememberToken();
      $table->timestamps();
      $table->softDeletes();
      $table->unique(['email', 'deleted_at'], 'users_email_deleted_at_unique');
      $table->unique(['login_id', 'deleted_at'], 'users_login_id_deleted_at_unique');
    });
  }

  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::dropIfExists('admins');
  }
}
/var/www/laravel
$ php artisan migrate
config/auth.php

'guards' => [
  'web' => [
    'driver' => 'session',
    'provider' => 'users',
  ],

  // 追加
  'admin' => [
    'driver' => 'session',
    'provider' => 'admins',
  ],

  'api' => [
    'driver' => 'token',
    'provider' => 'users',
    'hash' => false,
  ],
],

'providers' => [
  'users' => [
    'driver' => 'eloquent',
    'model' => App\Models\User::class,
  ],
  // 追加
  'admins' => [
    'driver' => 'eloquent',
    'model' => App\Models\Admin::class,
  ],

  // 'users' => [
  //     'driver' => 'database',
  //     'table' => 'users',
  // ],
],

'passwords' => [
  'users' => [
    'provider' => 'users',
    'table' => 'password_resets',
    'expire' => 60,
    'throttle' => 60,
  ],

  // 追加
  'admins' => [
    'provider' => 'admins',
    'table' => 'password_resets',
    'expire' => 60,
    'throttle' => 60,
  ],
],
app/Models/Admin.php
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;

class Admin extends Authenticatable
{
  use Notifiable;
  use SoftDeletes;

  protected $table = 'admins';

  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = [
    'name', 'email', 'login_id', 'password',
  ];

  /**
   * The attributes that should be hidden for arrays.
   *
   * @var array
   */
  protected $hidden = [
    'password', 'remember_token',
  ];

  /**
   * The attributes that should be cast to native types.
   *
   * @var array
   */
  protected $casts = [
    'email_verified_at' => 'datetime',
  ];
}
app/Http/Middleware/Authenticate.php

<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Support\Facades\Route;  // 追加

class Authenticate extends Middleware
{

  protected function redirectTo($request)
  {
    if (!$request->expectsJson()) {
      // 変更
      if (Route::is('admin.*')) {
        return route('admin.login');
      } else {
        return route('login');
      }
    }
  }
}
app/Http/Middleware/RedirectIfAuthenticated.php
<?php

namespace App\Http\Middleware;

use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure  $next
   * @param  string|null  $guard
   * @return mixed
   */
  public function handle($request, Closure $next, $guard = null)
  {
    if (Auth::guard($guard)->check()) {
    // 変更
      if ($guard === 'user') {
        return redirect()->route('currentUser');
      } elseif ($guard === 'admin') {
        return redirect()->route('currentAdmin');
      }
    }

    return $next($request);
  }
}
/var/www/laravel
$ mkdir -p app/Http/Controllers/Admin/Auth
$ cp app/Http/Controllers/Auth/{RegisterController,LoginController}.php app/Http/Controllers/Admin/Auth/
routes/api.php
Route::group(['middleware' => 'api'], function () {

  Route::get('/current_user', function () {
    return Auth::user();
  })->name('currentUser');

  Route::namespace('Auth')->group(function() {
    Route::post('/register', 'RegisterController@register')->name('register');
    Route::post('/login', 'LoginController@login')->name('login');

    Route::middleware('auth')->group(function() {
      Route::post('/logout', 'LoginController@logout')->name('logout');
    });
  });

  // 追加
  Route::get('/current_admin', function () {
    return Auth::guard('admin')->user();
  })->name('currentAdmin');

  Route::namespace('Admin')->prefix('admin')->name('admin.')->group(function () {
    Route::post('register', 'Auth\RegisterController@register')->name('register');
    Route::post('login', 'Auth\LoginController@login')->name('login');
    Route::post('logout', 'Auth\LoginController@logout')->name('logout');
  });

  Route::middleware('auth')->group(function () {
    // 一般認証が必要なAPI
  });

  Route::middleware('auth:admin')->group(function () {
    // 管理者認証が必要なAPI
  });

});
app/Http/Controllers/Admin/Auth/RegisterController.php
<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\Admin;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;

class RegisterController extends Controller
{
  /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

  use RegistersUsers;

  protected function guard()
  {
    return Auth::guard('admin');
  }

  // 中略

  /**
   * Create a new controller instance.
   *
   * @return void
   */
  public function __construct()
  {
    $this->middleware('guest:admin');
  }

  /**
   * Get a validator for an incoming registration request.
   * 'users'を'admins'に変えるだけ
   * @param  array  $data
   * @return \Illuminate\Contracts\Validation\Validator
   */
  protected function validator(array $data)
  {
    return Validator::make($data, [
      'name' => ['required', 'string', 'max:255'],
      'login_id' => ['required', 'regex:/^[\w\-\._]+$/i', 'min:8', 'max:20', Rule::unique('admins', 'login_id')->whereNull('deleted_at')],
      'email' => ['required', 'string', 'email', 'max:255', Rule::unique('admins', 'email')->whereNull('deleted_at')],
      'password' => ['required', 'string', 'min:8', 'max:20', 'confirmed'],
    ]);
  } 

  /**
   * @param Request $request
   * @param Admin $admin
   * @return Admin
   */
  protected function registered(Request $request, $admin)
  {
    return $admin;
  }
app/Http/Controllers/Admin/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use App\Models\Admin;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
  /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

  use AuthenticatesUsers;

  /**
   * Where to redirect users after login.
   *
   * @var string
   */
  protected $redirectTo = RouteServiceProvider::HOME;

  protected function guard()
  {
    return Auth::guard('admin');
  }


  /**
   * Create a new controller instance.
   *
   * @return void
   */
  public function __construct()
  {
    $this->middleware('guest:admin')->except('logout');
  }

  /**
   * @return string
   */
  public function username()
  {
    return 'login_id';
  }

  /**
   * @param Request
   * @param Admin $admin
   * @return Admin
   */
  protected function authenticated(Request $request, $admin)
  {
    return $admin;
  }

  /**
   * @param Request $request
   */
  protected function loggedOut(Request $request)
  {
    Auth::logout();
    $request->session()->regenerate();
    return response()->json();
  }
}

Vue側の実装

~/workspace/myapp/resources/ts
$ cp types/Models/User.ts types/Models/Admin.ts \
> store/auth.ts store/admin.ts
resources/ts/types/Models/Admin.ts
- export type User = {
+ export type Admin = {
  id: number
  name: string
  [k: string]: any
} | null
resources/ts/store/admin.ts
- import { User } from '@/types/Models/User'
+ import { Admin } from '@/types/Models/Admin'
import { RegisterRequest, LoginRequest } from '@/types/Auth'
import { UNPROCESSABLE_ENTITY } from '@/util'
import router from '@/router'

export type State = {
-  user: User
+  admin: Admin
}

const state = {
-  user: null,
+  admin: null,
}

const getters = {
-  isLogin: (state: State): boolean => !!state.user,
-  userId: (state: State): number | null => (state.user ? state.user.id : null),
-  userName: (state: State): string => (state.user ? state.user.name : ''),
+  isLogin: (state: State): boolean => !!state.admin,
+  adminId: (state: State): number | null => (state.admin ? state.admin.id : null),
+  adminName: (state: State): string => (state.admin ? state.admin.name : ''),
}

const mutations = {
-   setUser(state: State, user: User): void {
-   state.user = user
+   setAdmin(state: State, admin: Admin): void {
+   state.admin = admin
  },
}

const actions = {
  async register(context, data: RegisterRequest): Promise<void> {
    await window.axios
-      .post('/api/register', data)
-      .then((response) => {
-        context.commit('setAdmin', response.data)
+      .post('/api/admin/register', data)
+      .then((response) => {
+        context.commit('setUser', response.data)
        context.commit(
          'error/setErrors',
          {
            messages: null,
            status: null,
          },
          { root: true }
        )
-        router.push('/mypage')
+        router.push('/admin/mypage')
      })
      .catch((err) => {
        if (err.response.status === UNPROCESSABLE_ENTITY) {
          context.commit(
            'error/setErrors',
            {
              messages: err.response.data.errors,
              status: err.response.status,
            },
            { root: true }
          )
        }
      })
  },

  async login(context, data: LoginRequest): Promise<void> {
    await window.axios
-      .post('/api/login', data)
-      .then((response) => {
+      .post('/api/admin/login', data)
+      .then((response) => {
-        context.commit('setUser', response.data)
+        context.commit('setAdmin', response.data)
        context.commit(
          'error/setErrors',
          {
            messages: null,
            status: null,
          },
          { root: true }
        )
-        router.push('/mypage')
+        router.push('/admin/mypage')
      })
      .catch((err) => {
        if (err.response.status === UNPROCESSABLE_ENTITY) {
          context.commit(
            'error/setErrors',
            {
              messages: err.response.data.errors,
              status: err.response.status,
            },
            { root: true }
          )
        } else {
          context.commit('error/setErrors',
          {
            messages: err.response,
            status: err.response.status,
          },
          { root: true }
          )
        }
      })
  },

  async logout(context): Promise<void> {
    await window.axios
-      .post('/api/logout')
+      .post('/api/admin/logout')
      .then((response) => {
-        context.commit('setUser', null)
-        router.push('/login')
+        context.commit('setAdmin', null)
+        router.push('/admin/login')
      })
      .catch((err) => {
        context.commit(
          'error/setErrors',
          {
            messages: err.response,
            status: err.response.status,
          },
          { root: true }
        )
      })
  },

-  async currentUser(context): Promise<void> {
+  async currentAdmin(context): Promise<void> {
    await window.axios
-      .get('/api/current_user')
-      .then((response) => {
-        const user = response.data || null
-        context.commit('setUser', user)
+      .get('/api/admin/current_admin')
+      .then((response) => {
+        const admin = response.data || null
+        context.commit('setAdmin', admin)
      })
      .catch((err) => {
        context.commit(
          'error/setErrors',
          {
            messages: err.response.data.errors,
            status: err.response.status,
          },
          { root: true }
        )
      })
  },
}

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions,
}
resources/ts/store/index.ts
import Vue from 'vue'
import Vuex from 'vuex'

import auth from './auth'
+ import admin from './admin'
import error from './error'
Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    auth,
+    admin,
    error
  },
})

export default store
resources/ts/app.ts
import Vue from 'vue'
// ルーティングの定義をインポートする
import router from './router'
// ルートコンポーネントをインポートする
import App from './App.vue'
import store from './store'

import bootstrap from './bootstrap'

bootstrap()

const createApp = async () => {
  await store.dispatch('auth/currentUser')
+  await store.dispatch('admin/currentAdmin')
  new Vue({
    el: '#app',
    router,
    store,
    render: (h) => h(App),
  })
}

createApp()

view

~/workspace/myapp/resources/ts
$ mkdir -p layouts/admin pages/admin/mypage
$ touch layouts/admin/{Default,MyPageLayout}.vue \
> pages/admin/mypage/Index.vue

$ cp pages/{Register,Login}.vue pages/admin/
resources/ts/layouts/admin/Default.vue
<template>
  <div>
    <header>
      <nav>
        <ul v-if="!isLogin">
          <li><router-link tag="a" to="/admin/login">管理者ログイン</router-link></li>
          <li><router-link tag="a" to="/admin/register">管理者登録</router-link></li>
        </ul>
        <ul v-else>
          <li @click="logout">ログアウト</li>
        </ul>
      </nav>
    </header>
    <main>
      <div class="container">
        <router-view />
      </div>
    </main>
  </div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import { mapGetters } from 'vuex'
@Component({
  computed: {
    ...mapGetters({
      isLogin: 'admin/isLogin'
    })
  }
})

export default class AdminLayout extends Vue {
  async logout(): Promise<void> {
    await this.$store.dispatch('admin/logout')
  }
}
</script>
resources/ts/layouts/admin/MyPageLayout.vue
<template>
  <div>
    <header>
      <nav>
        <ul v-if="!isLogin">
          <li><router-link tag="a" to="/admin/login">管理者ログイン</router-link></li>
          <li><router-link tag="a" to="/admin/register">管理者登録</router-link></li>
        </ul>
        <ul v-else>
          <li @click="logout">ログアウト</li>
        </ul>
      </nav>
    </header>
    <main>
      <div class="container">
        <router-view :admin="admin" />
      </div>
    </main>
  </div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import { mapState, mapGetters } from 'vuex'
@Component({
  computed: {
    ...mapState({
      admin: state => state.admin.admin
    }),
    ...mapGetters({
      isLogin: 'admin/isLogin',
    }),
  }
})

export default class AdminMyPageLayout extends Vue {
  async logout(): Promise<void> {
    await this.$store.dispatch('admin/logout')
  }
}
</script>
resources/ts/pages/admin/Login.vue
<template>
<div>
  <h1>管理者ログイン</h1>
  <form @submit.prevent="login">
    <div v-for="(formItem, index) in submitData" :key="index">
      <p v-if="formItem.errorMessages">{{ formItem.errorMessages[0] }}</p>
      <input
        v-if="formItem.type==='text'"
        type="text"
        v-model="formItem.value"
        :placeholder="formItem.placeholder"
        @keyup="validation(formItem)"
        required
      >
      <input
        v-else-if="formItem.type==='password'"
        type="password"
        v-model="formItem.value"
        @keyup="validation(formItem)"
        :placeholder="formItem.placeholder"
        required
      >
    </div>
    <div>
      <button :disabled="disabled">ログイン</button>
    </div>
  </form>
</div>
</template>

<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator'
import { Form } from '@/types/Form'
import FormValidator from '@/mixins/formValidator'

@Component
export default class Login extends Mixins(FormValidator) {

  submitData: Form = {
    login_id: {
      name: 'login_id',
      type: 'text',
      value: '',
      rules: [(val: string) => !!val || 'ログインIDは必須です'],
      errorMessages: [],
      placeholder: 'login_id',
    },
    password: {
      name: 'password',
      type: 'password',
      value: '',
      rules: [(val: string) => !!val || 'パスワードは必須です'],
      errorMessages: [],
      placeholder: 'at least 8 chars.',
    },
  }

  async login(): Promise<void> {
    if (this.disabled) {
      Object.keys(this.submitData).forEach((key: string): void => {
        this.validation(this.submitData[key])
      })
    } else {
      const formData = new FormData()
      formData.append('login_id', this.submitData.login_id.value)
      formData.append('password', this.submitData.password.value)
      await this.$store.dispatch('admin/login', formData)
    }
  }

}
</script>
resources/ts/pages/admin/Register.vue
<template>
<div class="container">
  <h1>管理者登録</h1>
  <form @submit.prevent="register">
    <div v-for="(formItem, index) in submitData" :key="index">
      <p v-if="formItem.errorMessages">{{ formItem.errorMessages[0] }}</p>
      <input
        v-if="formItem.type==='text'"
        type="text"
        v-model="formItem.value"
        :placeholder="formItem.placeholder"
        @keyup="validation(formItem)"
        required
      >
      <input
        v-else-if="formItem.type==='email'"
        type="email"
        v-model="formItem.value"
        :placeholder="formItem.placeholder"
        @keyup="validation(formItem)"
        required
      >
      <input
        v-else-if="formItem.type==='password'"
        type="password"
        v-model="formItem.value"
        @keyup="validation(formItem)"
        :placeholder="formItem.placeholder"
        required
        >
    </div>
    <div>
      <button :disabled="disabled">管理者登録</button>
    </div>
  </form>
</div>
</template>

<script lang="ts">
import { Component, Mixins} from 'vue-property-decorator'
import { Form } from '@/types/Form'
import FormValidator from '@/mixins/formValidator'

@Component
export default class Register extends Mixins(FormValidator) {

  submitData: Form = {
    name: {
      name: 'お名前',
      type: 'text',
      value: '',
      rules: [
        (val: string) => !!val || '必須項目です',
        (val: string) => (val.length >= 2 && val.length <= 20) || '2文字以上20文字以下で設定してください',
      ],
      errorMessages: [],
      placeholder: 'your nickname',
    },
    email: {
      name: 'メールアドレス',
      type: 'email',
      value: '',
      rules: [
        (val: string) => !!val || '必須項目です',
        (val: string) => !!val.match(/^\w+[\w\-\._]*\w+@\w+[\w\-\._]*\.\w+[\w\-\._]*[A-Za-z]+$/i) || 'メールアドレスの形式が正しくありません'
      ],
      errorMessages: [],
      placeholder: 'sample@example.com',
    },
    login_id: {
      name: 'ログインID',
      type: 'text',
      value: '',
      rules: [
        (val: string) => !!val || '必須項目です',
        (val: string) => !!val.match(/^[\w\-\._]+$/g) || '半角英数字、「.」、「_」、「-」のみ使えます',
        (val: string) => val.length >= 8 && val.length <= 20 || '8文字以上20文字以下で入力してください'
      ],
      errorMessages: [],
      placeholder: 'login ID',
    },
    password: {
      name: 'パスワード',
      type: 'password',
      value: '',
      rules: [
        (val: string) => !!val || '必須項目です',
        (val: string) => !!val.match(/^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)[a-zA-Z\d]+$/) || '半角小文字、半角大文字、数字をそれぞれ1種類以上含めてください',
        (val: string) => (val.length >= 8 && val.length <= 20) || '8文字以上20文字以下で設定してください',
      ],
      errorMessages: [],
      placeholder: 'at leeast 8 chars.',
    },
    password_confirmation: {
      name: 'パスワード(確認用)',
      type: 'password',
      value: '',
      rules: [
        (val: string) => !!val || '必須項目です',
        (val: string) => this.submitData.password.value === val || 'パスワードが一致しません'
      ],
      errorMessages: [],
      placeholder: 'confirm',
    },
  }

  async register(): Promise<void> {
    if (this.disabled) {
      Object.keys(this.submitData).forEach((key: string): void => {
        this.validation(this.submitData[key])
      })
    } else {
      const formData = new FormData()
      formData.append('name', this.submitData.name.value)
      formData.append('email', this.submitData.email.value)
      formData.append('login_id', this.submitData.login_id.value)
      formData.append('password', this.submitData.password.value)
      formData.append('password_confirmation', this.submitData.password_confirmation.value)
      await this.$store.dispatch('admin/register', formData)
    }
  }

}
</script>
resources/ts/pages/admin/mypage/Index.vue
<template>
<div>
  <p v-if="!!admin">{{ admin.name }}さん、管理者画面へようこそ</p>
</div>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator'
import { Admin } from '@/types/Models/Admin'

@Component
export default class AdminMyPageIndex extends Vue {
  @Prop({ type: Object, required: true, default: null })
  admin!: Admin
}
</script>
resources/ts/router.ts
import Vue from 'vue'
import VueRouter from 'vue-router'
// ページコンポーネントをインポートする
import Index from './pages/Index.vue'

// レイアウト
import DefaultLayout from './layouts/Default.vue'
import MyPageLayout from './layouts/MyPageLayout.vue'
+ import AdminDefaultLayout from './layouts/admin/Default.vue'
+ import AdminMyPageLayout from './layouts/admin/MyPageLayout.vue'

// ユーザー画面
import Login from './pages/Login.vue'
import Register from './pages/Register.vue'
import MyPageIndex from '@/pages/mypage/Index.vue'

// 管理者画面
+ import AdminLogin from '@/pages/admin/Login.vue'
+ import AdminRegister from '@/pages/admin/Register.vue'
+ import AdminMyPageIndex from '@/pages/admin/mypage/Index.vue'

import store from './store'
// VueRouterプラグインを使用する
Vue.use(VueRouter)

// パスとコンポーネントのマッピング
const routes = [
  {
    path: '/',
    component: DefaultLayout,
    children: [
      {
        path: '/',
        component: Index,
      },
      {
        path: '/register',
        component: Register,
        beforeEnter (to, from, next) {
          if (store.getters['auth/isLogin']) {
            next('/')
          } else {
            next()
          }
        }
      },
      {
        path: '/login',
        component: Login,
        beforeEnter (to, from, next) {
          if (store.getters['auth/isLogin']) {
            next('/')
          } else {
            next()
          }
        }
      },
    ],
  },
  {
    path: '/mypage',
    component: MyPageLayout,
    beforeEnter (to, from, next) {
      if (!store.getters['auth/isLogin']) {
        next('/login')
      } else {
        next()
      }
    },
    children: [
      {
        path: '/',
        component: MyPageIndex,
      }
    ],
  },

  // ↓追加
  {
    path: '/admin',
    component: AdminDefaultLayout,
    children: [
      {
        path: '/',
        component: AdminRegister,
        beforeEnter (to, from, next) {
          if (store.getters['admin/isLogin']) {
            next('/admin/mypage')
          } else {
            next('/admin/login')
          }
        }
      },
      {
        path: 'register',
        component: AdminRegister,
        beforeEnter (to, from, next) {
          if (store.getters['admin/isLogin']) {
            next('/admin/mypage')
          } else {
            next()
          }
        }
      },
      {
        path: 'login',
        component: AdminLogin,
        beforeEnter (to, from, next) {
          if (store.getters['admin/isLogin']) {
            next('/admin/mypage')
          } else {
            next()
          }
        }
      },
    ],
  },
  {
    path: '/admin/mypage',
    component: AdminMyPageLayout,
    beforeEnter (to, from, next) {
      if (!store.getters['admin/isLogin']) {
        next('/admin/login')
      } else {
        next()
      }
    },
    children: [
      {
        path: '/',
        component: AdminMyPageIndex,
      }
    ],
  },
]

const router = new VueRouter({
  mode: 'history',    //URL中の#(ハッシュ)を消す
  routes
})

export default router
0
1
0

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
0
1