
- ログインユーザーにしか見せたくないページがある(アカウントページなど)
- ログインせずにアクセスしたらログインフォームに飛ばす
- ちゃんとログインしてくれたら、もともとアクセスしたかったページにリダイレクトする
vuexを使えばできる。
↓
axios.get("api/loginCheck") .then(response => { this.$router.push(this.$router.go(-1)) })
ログイン後のリダイレクト先を、ハイライト部分のようにするだけでできた。
単純に1個前のページに戻ってね って意味。
前提条件
- LaravelとVueを利用
- Laravelのsanctumによる認証システムが構築済みであること
- ログインフォームとログイン用APIも完成していること
Vuexがインストール済みで利用できること←別に要らんかった
処理の流れ
ログインせずにアカウントページなどのURLにアクセス
↓
ログインしていないので、ログインフォームのページにリダイレクト
↓
ログインしたらトップページではなく、リダイレクトされる前のページに飛ぶ
ばり親切な設計やん!
やり方
コードはこんな感じ。
自分の環境に合わせて書き換えて!
ログインチェックのAPI
ログインしているか判断するAPIを作成
//api.php Route::middleware('auth:sanctum')->get('/loginCheck',function (Request $request) { });
このAPIを発動させると、ログインしていない場合にだけ
401 (Unauthorized)
のエラーを返してくれる。
これを使って、ログインユーザーとログインしていないユーザーでの条件分岐を行っていく。
最初のアクセス先を覚えておくためのvuex
↓ごめん、こんなややこしいことしなくてもできたからここは飛ばして
//プロジェクトディレクトリ\resources\js\store\index.js import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); const store = new Vuex.Store({ state: { message: null, name: null, token: null, jumpTo:'/',//リダイレクト先(初期値はトップページ) }, getters: { getUserName(state) { return state.name } }, mutations: { message(state, message) { state.message = message //ログインしてね!ってメッセージを格納する場所 }, jumpTo(state,jumpTo){ state.jumpTo = jumpTo //ログインページに飛ばされた人が本来アクセスしたかったパスを記憶する場所 }, resetState(state) { state.message = null //ログイン後にメッセージを削除 state.jumpTo = '/' //ログイン後はリダイレクト先は忘れる }, } }, ); export default store;
ログインしている人にしか見せたくないページ
アカウントページなどログインしている人以外にはアクセスさせないページのコンポーネント。
ページの内容はなんでもいいので、mountedだけ今回は記載。
//Hoge.vue mounted() { axios.get("/api/loginCheck") .then(response => { console.log(response) }) .catch(error => { console.log(error) this.$store.commit("message",'ログインしてください。')//なんでログインページに飛ばされたかが分かるメッセージ //↓不要だった //this.$store.commit("jumpTo", this.$route.path) //このページのパスをvuexのstateに格納して後から呼び出せるようにする this.$router.push("/login") //ログイン画面にジャンプ }) },
ジャンプ先を把握してくれているナイスなログインページ
ログインフォームとログインAPIは完成している前提なので、スクリプトの部分だけを記載
//Login.vue data() { return { message: null, jumpTo: '/', //本来はトップページにリダイレクト } }, mounted() { this.message = this.$store.state.message //「ログインしてください」等のメッセージがあれば、アクセス元ページからvuex経由で受け取り this.jumpTo = this.$store.state.jumpTo //ログインを求められて飛ばされた人が本来アクセスしたかったパス }, methods: { //ログイン処理のメソッド Login() { axios.get("/api/ログインAPI") .then(response => { this.$store.commit("resetState") //vuexのstateに保存されているメッセージをリセット //this.$router.push(this.jumpTo) //本来アクセスしたかったページにリダイレクト this.$router.push(this.$router.go(-1)) //段順に1個前にアクセスしていたページにリダイレクト }) .catch((error => { //console.log(error) this.message = 'ユーザー名またはパスワードが違います。' })) } },
ログイン処理に成功したら、さっき閲覧できなかった最初にアクセスしたページに飛ばす。
vuexくんのstateが覚えてるわけやな。
で、このままだとログインしなおすたびに「最初にアクセスしたページ」飛ばされてしまうので、
//プロジェクトディレクトリ\resources\js\store\index.js import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); const store = new Vuex.Store({ state: { message: null, name: null, token: null, jumpTo:'/',//リダイレクト先(初期値はトップページ) }, getters: { getUserName(state) { return state.name } }, mutations: { message(state, message) { state.message = message //ログインしてね!ってメッセージを格納する場所 }, jumpTo(state,jumpTo){ state.jumpTo = jumpTo //ログインページに飛ばされた人が本来アクセスしたかったパスを記憶する場所 }, resetState(state) { state.message = null //ログイン後にメッセージを削除 state.jumpTo = '/' //ログイン後はリダイレクト先は忘れる }, } }, ); export default store;
ちなみにvuexに保存しているのでページをリロード(再読み込み・更新)すると消える。
消えたほうがいいと思ってこのような設計にしてる。