vue-router보다 먼저 무언가를 실행하는 방법
첫 번째 SPA를 만들고 있는데 몇 가지 문제가 있어요.설계 방법은 다음과 같습니다.
- Laravel & Laravel Views는 로그인 및 등록 관련 페이지를 처리합니다.
- SPA는 로그인한 사용자 페이지에서 시작됩니다.
- my app.js는 기본 VueJS 앱을 정의합니다.
mounted()로그인한 사용자의 상태(VUEX)를 설정하는 방법.이상적으로는 Larabel 백엔드에 대한 Axios 호출을 통해 사용자 세부 정보를 가져오고 VUEX 상태를 채우는 것이 전부입니다. - 사용하고 있다
beforeEnter()허가된 사용자만 루트로 이동할 수 있도록 루트 정의의 메서드를 지정합니다.
이것이 내가 문제에 직면한 부분이다.사용자가 로그인하면 vuex가 설정되기 전에 라우터가 실행되는 것처럼 보입니다.URL /dashboard 및 /user/1이 있다고 합니다.user/1에 접속하려고 하면 어플리케이션을 로드한 후에 정상적으로 동작합니다.단, user/1에 있을 때 웹 페이지를 새로 고치면 라우터가beforeEnter사용자의 vuex 상태를 찾을 수 없으므로 대시보드로 사용자를 리디렉션합니다.이는 라우터가 동작하고 있을 때beforeEnter신규 페이지 로드인 경우 사용자 Vuex 상태에 액세스할 수 없거나 액세스할 수 있지만 값은 아직 설정되지 않았습니다.
이 때문에 가장 큰 문제는 루트 페이지가 항상 대시보드에 도착하고 사용자가 루트로 이동해야만 작동하기 때문에 직접 링크할 수 없다는 것입니다.이 상황에 어떻게 대처해야 할까요?
이게 내가 결국 하게 된 일이야.Vue를 초기화하는 함수를 정의했습니다.
app.js의 마지막에 Axios를 사용하여 Ajax를 통해 현재 사용자를 가져옵니다.에서then약속의 방법, 나는 그것을 설정했다.store약속에서 받은 사용자 세부사항을 입력하고 위의 Vue 초기화에서 정의한 함수를 호출합니다.이렇게 하면 vue가 초기화되었을 때 스토어 사용자는 이미 데이터를 가지고 있습니다.
코드 변경은 매우 미미하여 기존 악시오 구현을 변경할 필요가 없었습니다.
이것이 새로운 구현입니다.
Axios.get('/api/user/info')
.then(response => {
(new Vue).$store.commit('setUser', response.data);
initializeVue();
})
.catch(error => initializeVue());
function initializeVue()
{
window.app = new Vue({
el: '#app',
router,
components: {
UserCard,
Sidebar,
},
methods: mapMutations(['setUser']),
computed: mapState(['user']),
});
}
버스로 $root를 사용하고 마지막 수단으로 VueX에 접속합니다.여기 제가 작업하고 있는 플러그 인에서 몇 가지 코드를 제거했습니다.당신이 코드에 드랍할 수 있도록 약간 수정했습니다.
이 구성에서는 VUE CLI를 지원합니다.
세션 만료에 대해 걱정하지 마십시오. 가로채기는 Laravel로부터의 401 응답을 감시하면 사용자에게 재인증을 요구할 수 있습니다.
bootstrap.js에서 axios 구성을 삭제하고 이 설정으로 대체하고 액세스 제어 허용 오리진을 구성합니다. 와일드카드는 로컬 dev에 사용할 수 있습니다.
axios.defaults.withCredentials = true;
axios.defaults.headers.common = {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': undefined,
'Access-Control-Allow-Origin': '*'
};
axios.interceptors.response.use(
function (response) {
if(response.headers.hasOwnProperty('x-csrf-token')) {
axios.defaults.headers['X-CSRF-TOKEN'] = response.headers['x-csrf-token'];
}
return response;
},
function (error) {
if(typeof error !== 'object' || !error.response) {
return Promise.reject(error);
}
if(error.response.hasOwnProperty('status')) {
switch(error.response.status) {
case 401:
case 419:
// DO RE-AUTHENTICATE CALL
break;
}
}
return Promise.reject(error);
}
);
나머지는...
in main.js
data() {
return {
user: {},
authenticating: false
}
},
computed: {
isAuthenticated() {
// Check a credential only an authorized user would have.
if(this.$router.app.hasOwnProperty('user') === false || this.$router.app.user === null) {
return false;
}
return this.$router.app.user.hasOwnProperty('id');
}
},
methods: {
checkAuth: function () {
this.$set(this.$router.app, 'authenticating', true);
axios.get('/auth/user').then(response => {
this.$set(this.$router.app, 'user', response.data.user);
if (this.$router.app.isAuthenticated()) {
this.$router.push(this.$router.currentRoute.query.redirect || '/', () => {
this.$set(this.$router.app, 'authenticating', false);
});
}
}).catch(error => {
// TODO Handle error response
console.error(error);
this.$set(this.$router.app, 'user', {});
}).finally(() => {
this.$set(this.$router.app, 'authenticating', false);
});
},
login: function (input) {
axios.post('/login', input).then(response => {
this.$set(this.$router.app, 'user', response.data.user);
this.$router.push(this.$router.currentRoute.query.redirect || '/');
}).catch(error => {
// TODO Handle errors
console.error(error);
});
},
logout: function () {
axios.post('/logout').then(response => {
this.$set(this.$router.app, 'user', {});
this.$nextTick(() => {
window.location.href = '/';
});
}).catch(error => {
console.error(error);
});
},
}
beforeCreate: function () {
this.$router.beforeResolve((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth) && !this.$router.app.isAuthenticated()) {
next({
name: 'login',
query: {
redirect: to.fullPath
}
});
return;
}
next();
});
}
[ Auth / Login Controller ]으로 설정합니다.php add 메서드
public final function authenticated(Request $request)
{
return response()->json([
'user' => Auth::user()
]);
}
앱/Http/Middleware/AfterMiddleware를 만듭니다.php 새로운 CSRF 토큰은 모든 요청이 아닌 변경된 경우에만 반환됩니다.Axios 인터셉터는 검출되면 새로운 토큰을 수집합니다.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Cookie;
class AfterMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Cookie::get('X-CSRF-TOKEN',false) !== csrf_token())
return $next($request)->header('X-CSRF-TOKEN',csrf_token());
return $next($request);
}
}
이 설정을 사용하면 스태틱로그인 폼을 Vue 로그인 폼으로 효과적으로 대체할 수 있습니다.
라우터의 셋업은 다음과 같습니다.
new Router({
mode: 'history',
routes: [
{
path: '/login',
name: 'login',
component: AuthLogin,
meta: {
requiresAuth: false,
layout: 'auth'
}
},
{
path: '/login/recover',
name: 'login-recover',
component: AuthLoginRecover,
meta: {
requiresAuth: false,
layout: 'auth'
}
},
{
path: '/',
name: 'index',
component: Dashboard,
meta: {
requiresAuth: true,
layout: 'default'
}
},
{
path: '/settings',
name: 'settings',
component: Settings,
meta: {
requiresAuth: true,
layout: 'default'
}
}
]
});
언급URL : https://stackoverflow.com/questions/53703581/how-to-get-something-to-run-before-vue-router
'programing' 카테고리의 다른 글
| Java 핵심 라이브러리의 GoF 설계 패턴 예시 (0) | 2022.08.16 |
|---|---|
| Vue + Jest 정의되지 않은 속성 '기본값'을 읽을 수 없습니다. (0) | 2022.08.16 |
| Vue.js & Vuex - 액세스 토큰을 스토어에 저장하고 사용자를 URL로 리다이렉트하여 로그인을 합니다. (0) | 2022.08.16 |
| v- for 렌더링 안 함 구성 요소 (0) | 2022.08.16 |
| 기존 vuejs 프로젝트에 typescript 컴포넌트를 추가하려면 어떻게 해야 합니까? (0) | 2022.08.16 |