vue-springboot实现登录验证

 

首先做好准备工作,建好前后端项目,配置好。可参考https://segmentfault.com/a/1190000014211773?utm_source=tag-newest

前端:

1.发送登录请求,将后台返回的token保存进sessionStorage。

Login.vue


2.main.js中添加请求拦截器,每一个到后端的请求都带上token,未登录就是null,会被后端拦截

main.js

// 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';
//引入emlment-ui的提示功能
import {Message} from 'element-ui'
//引入vuex
import Vuex from 'vuex'
import store from './store'

Vue.use(Vuex)
Vue.use(ElementUI);

Vue.prototype.$message=Message
Vue.config.productionTip = false

// 引用axios,并设置基础URL为后端服务api地址
var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8001/lgtour'
axios.defaults.withCredentials  = true //请求发送cookie
// 将API方法绑定到全局
Vue.prototype.$axios = axios

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,//路由
  store:store,
  components: { App },
  template: '',
  emulateJSON:true,
  render: h => h(App)
})
// 添加请求拦截器,在请求头中加token
axios.interceptors.request.use(
  config => {
    if (window.sessionStorage.getItem('token')) {
      config.headers.token = window.sessionStorage.getItem('token')
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  });

3.router/index.js中添加导航守卫,让前端每一次路由跳转先判断是否登录。

index.js

import Vue from 'vue'
import Router from 'vue-router'
import Welcome from '@/components/Welcome'
import Login from '@/components/Login'

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'Welcome',
      component: Welcome
    },
    {
      path: '/admin/login',
      name: 'Login',
      component: Login
    },
    {
      path: '/userLogin',
      name: 'UserLogin',
      component: resolve => require(['@/components/user/UserLogin.vue'],resolve)
    }
  ]
})
// 导航守卫
// 使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆
router.beforeEach((to, from, next) => {
  if (to.path === '/admin/login') {
    next();
  } else {
    //console.log('before')
    let token = window.sessionStorage.getItem('token')
 
    if (token === null || token === '') {
      next('/admin/login');
    } else {
      next();
    }
  }
});
export default router;

后端:

所需依赖pom.xml



	4.0.0
	
		org.springframework.boot
		spring-boot-starter-parent
		2.3.0.RELEASE
		 
	
	com.zjjlg
	lgtour
	0.0.1-SNAPSHOT
	lgtour
	Demo project for Spring Boot

	
		1.8
	

	
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.mybatis.spring.boot
			mybatis-spring-boot-starter
			2.1.3
		

		
			mysql
			mysql-connector-java
			runtime
		
		
		
		
			com.alibaba
			druid
			1.1.8
		
		
		    org.projectlombok
		    lombok
		    true
		    1.18.12
		
		
		    com.alibaba
		    fastjson
		    1.2.47         
		
		
		    log4j
		    log4j
		    1.2.17
		
	
		
			org.springframework.boot
			spring-boot-starter-test
			test
			
				
					org.junit.vintage
					junit-vintage-engine
				
			
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	


配置文件,主要配置了druid数据源和log日志,打印数据库操作,方便测试

application.yml

server:
  port: 8001
  
spring:
  datasource:
#   数据源基本配置
    username: root
    password: 962464
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/lgtour?serverTimezone=GMT%2B8&
    type: com.alibaba.druid.pool.DruidDataSource
#   数据源其他配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
#   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙  
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true  
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
#    schema:
#    - classpath:sql/department.sql
#    - classpath:sql/employee.sql
#    initialization-mode: always
#  devtools:
#    restart:
#      enabled: true #是否支持热部署
#mybatis:
#  config-location: classpath:mybatis/mybatis-config.xml
#  mapper-locations: classpath:mybatis/mapper/*.xml
logging:
  level:
    com.example.demo.mapper: debug
mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml
    
    

后端返回给前端的数据对象,前后基本使用json传数据,将传递的信息封装起来

Result.java

package com.zjjtour.lgtour.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.Serializable;

/**
 * 前端返回对象
 */
@Data
public class Result implements Serializable {
    private static final long serialVersionUID = 1430633339880116031L;

    /**
     * 成功与否标志
     */
    private boolean success = true;
    /**
     * 返回状态码,为空则默认200.前端需要拦截一些常见的状态码如403、404、500等
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Integer status;
    /**
     * 编码,可用于前端处理多语言,不需要则不用返回编码
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String code;
    /**
     * 相关消息
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String msg;
    /**
     * 相关数据
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Object data;


    public Result() {}

    public Result(boolean success) {
        this.success = success;
    }

    public Result(boolean success, Integer status) {
        this.success = success;
        this.status = status;
    }

    public Result(boolean success, String code, String msg){
        this(success);
        this.code = code;
        this.msg = msg;
    }

    public Result(boolean success, Integer status, String code, String msg) {
        this.success = success;
        this.status = status;
        this.code = code;
        this.msg = msg;
    }

    public Result(boolean success, String code, String msg, Object data){
        this(success);
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

}

result生成工具类,快速创建result对象

ResultFactory.java

package com.zjjtour.lgtour.utils;

import com.zjjtour.lgtour.entity.Result;

/**
 * Result生成工具类
 */
public class ResultFactory {

    protected ResultFactory() {}

    public static Result newResult() {
        return new Result();

    }

    public static Result newResult(boolean success) {
        return new Result(success);
    }

    //
    // 业务调用成功
    // ----------------------------------------------------------------------------------------------------
    public static Result success() {
        return new Result();
    }

    public static Result success(String msg) {
        return new Result(true, null, msg);
    }

    public static Result success(String code, String msg) {
        return new Result(true, code, msg);
    }

    public static Result successWithStatus(Integer status) {
        return new Result(true, status);
    }

    public static Result successWithStatus(Integer status, String msg) {
        return new Result(true, status, null, msg);
    }

    public static Result successWithData(Object data) {
        return new Result(true, null, null, data);
    }

    public static Result successWithData(Object data, String msg) {
        return new Result(true, null, msg, data);
    }

    public static Result successWithData(Object data, String code, String msg) {
        return new Result(true, code, msg, data);
    }

    //
    // 业务调用失败
    // ----------------------------------------------------------------------------------------------------
    public static Result failure() {
        return new Result(false);
    }

    public static Result failure(String msg) {
        return new Result(false, null, msg);
    }

    public static Result failure(String code, String msg) {
        return new Result(false, code, msg);
    }

    public static Result failureWithStatus(Integer status) {
        return new Result(false, status);
    }

    public static Result failureWithStatus(Integer status, String msg) {
        return new Result(false, status, null, msg);
    }

    public static Result failureWithData(Object data) {
        return new Result(false, null, null, data);
    }

    public static Result failureWithData(Object data, String msg) {
        return new Result(false, null, msg, data);
    }

    public static Result failureWithData(Object data, String code, String msg) {
        return new Result(false, code, msg, data);
    }

}

跨域请求过滤器,解决前后分离跨域请求问题,配合@CrossOrigin注解使用

package com.zjjtour.lgtour.component;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/*
 * 允许跨域请求
 */

@Configuration
public class PortalCorsFilter extends CorsFilter{
	private static Logger logger = LoggerFactory.getLogger(PortalCorsFilter.class);
	public PortalCorsFilter() {
        super(configurationSource());
    }

    private static UrlBasedCorsConfigurationSource configurationSource() {
    	logger.info("init CorsFilter...");
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:8080");
        config.addAllowedHeader("*");
        config.setMaxAge(36000L);
        config.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

生成token的工具类:(网上找的)

TokenProccessor.java

package com.zjjtour.lgtour.component;

import java.security.MessageDigest;  
import java.security.NoSuchAlgorithmException;  
import java.util.Random;  
  
import sun.misc.BASE64Encoder;  
  
/**  
 * 生成Token的工具类  
 *  
 */  
public class TokenProccessor {  
      
     private TokenProccessor(){};  
     private static final TokenProccessor instance = new TokenProccessor();  
       
    public static TokenProccessor getInstance() {  
        return instance;  
    }  
  
    /**  
     * 生成Token  
     * @return  
     */  
    public String makeToken() {  
        String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";  
         try {  
            MessageDigest md = MessageDigest.getInstance("md5");  
            byte md5[] =  md.digest(token.getBytes());  
            BASE64Encoder encoder = new BASE64Encoder();  
            return encoder.encode(md5);  
        } catch (NoSuchAlgorithmException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
         return null;  
    }  
}  

请求拦截器,拦截所有前端请求,只放行登录请求。在拦截器中判断前端传递的token和后端存入session中的token是否相同,不同就拦截请求,返回错误信息,相同就放行。

MyWebConfig.java

package com.zjjtour.lgtour.component;

import java.io.IOException;
import java.io.PrintWriter;

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

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSON;
import com.zjjtour.lgtour.utils.ResultFactory;

@Configuration
public class MyWebConfig implements WebMvcConfigurer{
     /**
     * 登录session key
     */
    public final static String SESSION_KEY = "token";
    
    @Bean
    public SecurityInterceptor getSecurityInterceptor() {
        return new SecurityInterceptor();
    }
    
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());
        // 排除配置
        addInterceptor.excludePathPatterns("/error");
        addInterceptor.excludePathPatterns("/lgtour/login**");
        // 拦截配置
        addInterceptor.addPathPatterns("/lgtour/**");
    }
    //拦截器 内容
    private class SecurityInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            HttpSession session = request.getSession();
          //登录验证
    		System.out.println("前端token"+request.getHeader("token"));
    		
    		String header = request.getHeader("token");
    		String attribute = (String)session.getAttribute("stoken");
    		System.out.println("sessionToken"+attribute);
    		
    		if(header == null ||attribute == null ) {
    			returnJson(response, JSON.toJSONString(ResultFactory.failureWithStatus(401,"你还未登录或登录已过期,请先登录")));
    			return false;
    		}else if(!attribute.equals(header.split(" ")[1])) {
    			returnJson(response, JSON.toJSONString(ResultFactory.failureWithStatus(401,"你还未登录或登录已过期,请先登录")));
    			return false;
    		}else {
                return true;
    		}
        }
        //返回json数据
        private void returnJson(HttpServletResponse response, String json) throws Exception{
        	 PrintWriter writer = null;
             response.setCharacterEncoding("UTF-8");
             response.setContentType("text/html; charset=utf-8");
             try {
                 writer = response.getWriter();
                 writer.print(json);
      
             } catch (IOException e) {
             } finally {
                 if (writer != null)
                     writer.close();
             }
        }
    }
}

登录controller

LgAdminController.java

package com.zjjtour.lgtour.controller;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.zjjtour.lgtour.component.TokenProccessor;
import com.zjjtour.lgtour.entity.LgAdmin;
import com.zjjtour.lgtour.entity.Result;
import com.zjjtour.lgtour.service.LgAdminService;

@RestController
@ResponseBody
@CrossOrigin
@RequestMapping("/lgtour")
public class LgAdminController {
	@Autowired
	LgAdminService lgAdminService;

	@RequestMapping("/login")
	public Result login(@RequestBody LgAdmin admin,HttpSession session) {
		Result result = lgAdminService.login(admin);
		System.out.println(result);
		if(result.getStatus() == 200) {
			//创建token
			String token = TokenProccessor.getInstance().makeToken();
			session.setAttribute("stoken", token);
			result.setData(token);
			return result;
		}else {
			return result;
		}
		
	}
	@RequestMapping("/test")
	public void test() {
		System.out.println("通过拦截了");
	}
}

service

package com.zjjtour.lgtour.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zjjtour.lgtour.entity.LgAdmin;
import com.zjjtour.lgtour.entity.Result;
import com.zjjtour.lgtour.mapper.LgAdminMapper;
import com.zjjtour.lgtour.utils.ResultFactory;

@Service
public class LgAdminService {
	@Autowired
	LgAdminMapper lgAdminMapper;
	
	public Result login(LgAdmin admin) {
		LgAdmin get = lgAdminMapper.getByName(admin.getName());
		if(get == null) {
			return ResultFactory.failure("该用户不存在");
		}else if(!get.getPassword().equals(admin.getPassword())){
			return ResultFactory.failure("密码错误");
		}else {
			return ResultFactory.successWithStatus(200,"登录成功");
		}
	}
}

 mapper

package com.zjjtour.lgtour.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import com.zjjtour.lgtour.entity.LgAdmin;

@Mapper
public interface LgAdminMapper {
	
	@Select("select * from admin where name=#{name}")
	public LgAdmin getByName(String name);
}

 

 

你可能感兴趣的:(vue-springboot实现登录验证)