The combination of springboot+vue, back-end learning front-end (3) (front-end interceptor + back-end interceptor) is not logged in to access other pages, directly enter the login interface

insert image description here

Deal with the # issue

insert image description here
The address after the # number of the URL is called hash. We call this implementation method Hash mode, which is a very typical front-end routing method.
Another commonly used method is called History mode.

Use History mode

Newly added content in blue
insert image description here

Deploy the front-end to the back-end project (tomcat version needs to be increased from 8.5.23 to 9.0.56)

()
Click build in blue to complete the packaging. The successful status is as follows or the content location is as follows
insert image description here
through the command npm run build : If you want to merge the front end with the back end, you can put all the content in the dist into the wj\ of the back end project Under the src\main\resources\static folder

insert image description here

default error page

create a new page

import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Component
public class ErrorConfig implements ErrorPageRegistrar {
    
    

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
    
    
        ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/index.html");
        registry.addErrorPages(error404Page);
    }

}

Backend login interceptor

The logic of a simple interceptor is as follows:

1. When the user visits the URL, check whether it is a login page. If it is a login page, do not intercept it.
2. If the user visits a non-login page, check whether the user is logged in. If not, jump to the login page

LoginController adds session

insert image description here

LoginInterceptor

Determine whether there is a user attribute in the session, if it exists, it will be released, if it does not exist, it will jump to the login page.

package com.myli.base;


import com.myli.entity.User;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginInterceptor  implements HandlerInterceptor{
    
    

    @Override
    public boolean preHandle (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
    
    
        HttpSession session = httpServletRequest.getSession();
        String contextPath=session.getServletContext().getContextPath();
        String[] requireAuthPages = new String[]{
    
    
                "index",
        };
        String uri = httpServletRequest.getRequestURI();

        uri = StringUtils.remove(uri, contextPath+"/");
        String page = uri;

        if(begingWith(page, requireAuthPages)){
    
    
            User user = (User) session.getAttribute("user");
            if(user==null) {
    
    
                httpServletResponse.sendRedirect("login");
                return false;
            }
        }
        return true;
    }
    private boolean begingWith(String page, String[] requiredAuthPages) {
    
    
        boolean result = false;
        for (String requiredAuthPage : requiredAuthPages) {
    
    
            if(StringUtils.startsWith(page, requiredAuthPage)) {
    
    
                result = true;
                break;
            }
        }
        return result;
    }
}

The interceptor is configured in the project

package com.myli.base.config;

import com.myli.base.LoginInterceptor;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.*;

/**
 * @author Myli
 * @create 2023-02-22 17:29
 */
@SpringBootConfiguration
public class MyMvcConfig implements WebMvcConfigurer {
    
    

    @Bean
    public LoginInterceptor getLoginIntercepter() {
    
    
        return new LoginInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry){
    
    
        registry.addInterceptor(getLoginIntercepter()).addPathPatterns("/**").excludePathPatterns("/index.html");
    }
}

When accessing a URL, it will first judge whether it needs to be intercepted through Configurer, if necessary, trigger the interceptor LoginInterceptor, and then judge according to the custom rules.

/index is different from /index.html, that is to say, /index will trigger the interceptor but /index.html will not, but according to the judgment conditions we defined in the interceptor LoginInterceptor, the path starting with /index will be forwarded, Include index.html.

Because what we are doing is a single-page application, by configuring ErrorPage before, in fact, all access paths will be redirected to /index.html. We directly enter /index in the browser address bar to trigger the interceptor, redirect to /login through the interceptor, and then /login is judged by Configurer, triggering the interceptor again, because it is not in the path that needs to be intercepted, so it is released, the page It is redirected to /index.html. If the interception of /index.html is not canceled in Configurer, the interceptor will be triggered again and redirected to /login again.

Vuex and front-end login interceptor

Vuex, judge the user's login status at the front end

Download Vuex

npm install vuex --save
insert image description here

Introducing Vuex

Create a new folder store in the src directory, and create a new index.js file in this directory

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

Continue in that index.js

export default new Vuex.Store({
    
    
  state: {
    
    
    user: {
    
    
      username: window.localStorage.getItem('user' || '[]') == null ? '' : JSON.parse(window.localStorage.getItem('user' || '[]')).username
    }
  },
  mutations: {
    
    
    login (state, user) {
    
    
      state.user = user
      window.localStorage.setItem('user', JSON.stringify(user))
    }
  }
})

state means state, record user information
mutations method, when this method is triggered, we can assign value to our user object

localStorage: Local storage. When the project is opened, it will judge whether there is a user object in the local storage. If it exists, it will be taken out and the value of username will be obtained. Otherwise, username will be set to empty. In this way, as long as we do not clear the cache, the login status will always be saved.
insert image description here

Modify routing configuration

src\router\index.js
sets a requireAuth field

    {
    
    
     path: '/index',
     name: 'AppIndex',
     component: AppIndex,
     meta: {
    
    
       requireAuth: true
     }
   }

insert image description here

hook function

beforeEach() is the core of front-end interception
insert image description here

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import store from './store'

// 设置反向代理,前端请求默认发送到 http://localhost:8443/api
var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8443/api'

// 全局注册,之后可在其他组件中通过 this.$axios 发送数据
Vue.prototype.$axios = axios

Vue.config.productionTip = false

Vue.use(ElementUI)

// 钩子函数
// beforeEach() 函数判断访问的路径是否需要登录,
// router.beforeEach(),意思是在访问每一个路由前调用。
// 如果需要,判断 store 里有没有存储 user 的信息,
// 如果存在,则放行,否则跳转到登录页面,并存储访问的页面路径(以便在登录后跳转到访问页)。
router.beforeEach((to, from, next) => {
    
    
  if (to.meta.requireAuth) {
    
    
    if (store.state.user.username) {
    
    
      next()
    } else {
    
    
      next({
    
    
        path: 'login',
        query: {
    
    redirect: to.fullPath}
      })
    }
  } else {
    
    
    next()
  }
}
)
/* eslint-disable no-new */
new Vue({
    
    
  el: '#app',
  render: h => h(App),
  router,
  store,
  components: {
    
     App },
  template: '<App/>'
}
)

login.vue

Save the passed user information

<template>
  <body id="poster">
    <el-form class="login-container" label-position="left"
             label-width="0px">
      <h3 class="login_title">系统登录</h3>
      <el-form-item>
        <el-input type="text" v-model="loginForm.username"
                  auto-complete="off" placeholder="账号"></el-input>
      </el-form-item>
      <el-form-item>
        <el-input type="password" v-model="loginForm.password"
                  auto-complete="off" placeholder="密码"></el-input>
      </el-form-item>
      <el-form-item style="width: 100%">
        <el-button type="primary" style="width: 100%;background: #505458;border: none" v-on:click="login">登录</el-button>
      </el-form-item>
    </el-form>
  </body>
</template>

<script>

  export default {
    
    
    name: 'Login',
    data () {
    
    
      return {
    
    
        loginForm: {
    
    
          username: 'admin',
          password: '123'
        },
        responseResult: []
      }
    },
    methods: {
    
    
      login () {
    
    
        var _this = this
        console.log(this.$store.state)
        this.$axios
          .post('/login', {
    
    
            username: this.loginForm.username,
            password: this.loginForm.password
          })
          .then(successResponse => {
    
    
            if (successResponse.data.code === 200) {
    
    
              // var data = this.loginForm
              _this.$store.commit('login', _this.loginForm)
              var path = this.$route.query.redirect
              this.$router.replace({
    
    path: path === '/' || path === undefined ? '/index' : path})
            }
          })
          .catch(failResponse => {
    
    
          })
      }
    }
  }
</script>

<style>
  #poster {
    
    
    background:url("../assets/eva.jpg") no-repeat;
    background-position: center;
    height: 100%;
    width: 100%;
    background-size: cover;
    position: fixed;
  }
  body{
    
    
    margin: 0px;
  }
  .login-container {
    
    
    border-radius: 15px;
    background-clip: padding-box;
    margin: 90px auto;
    width: 350px;
    padding: 35px 35px 15px 35px;
    background: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
  }
  .login_title {
    
    
    margin: 0px auto 40px auto;
    text-align: center;
    color: #505458;
  }
</style>


login test

Enter the account password to log in
, check if it is saved
insert image description here
, then directly delete the data of the user line, and
re-enter the index page. If you go directly to the login interface, it is considered successful.
If there are messy errors, restart webstorm first, and then check whether the error exists. , if it exists, then resolve

Note: replace window.localStorage with window.sessionStorage in indesx.js under the store, the data can be kept until the browser is not closed, but it will not exist permanently!

Guess you like

Origin blog.csdn.net/m0_54765221/article/details/129210088
Recommended