SSM+Vue(拦截器及前后端登录对接)

SSM+Vue(拦截器及前后端登录对接)

一、java后端

第一步:实体类pojo

package com.dyt.entity;

import java.io.Serializable;
import java.util.Date;

/**
 * @author gdh
 */
public class Users implements Serializable {
	private static final long serialVersionUID = 1L;
    private String token;

	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}
}

第二步:编写用户登录UsersController

/**
 * @author gdh
 */
@Api(tags = "营养医师")
@Controller
@RequestMapping("users")
public class UsersController {

   protected final static Logger logger = LoggerFactory.getLogger(UsersController.class);

    @Reference
    private UsersService usersService;

    @ApiOperation(value = "营养医师登录")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "操作成功,返回新增${comments},保存在data集合元素中"),
            @ApiResponse(code = 500, message = "内部错误,信息由msg字段返回")
    })
    @RequestMapping(value = "Login",method=RequestMethod.POST)
    @ResponseBody
    public R<Users> Login (Users users){
        try {
            Users loginuser = usersService.adminLogin(users);
            return R.ok(loginuser);
        }catch(Exception e){
            logger.error("营养医师登录接口失败 error : {}", e);
            e.printStackTrace();
            return R.error("营养医师登录失败----->"+e.getMessage());
        }
    } 
}

第三步:接口层 UsersService

/**
 * @author gdh
 */
public interface UsersService {
    /**
	 * 用户登录
	 */
    Users adminLogin (Users users);
}

第四步:逻辑层UsersServiceImpl

/**
 * @author gdh
 */

@Service
@Component
//@Transactional
public class UsersServiceImpl implements UsersService {

    @Autowired
    private UsersDao usersDao;
    
    /**
     * 后台登录
     */
    public Users adminLogin(Users users) {
        Users users2 = new Users();
        users2.setIsDel(false);
        users2.setWorkCode(users.getWorkCode());
        users2.setName(users.getName());
        Users users1 = usersDao.queryUsers(users2);
        if (!StringUtil.isNullOrEmpty(users1)) {
            if (!users.getPassword().equals(users1.getPassword())) {
                users1.setStr("密码错误");
            } else {
                String token = JWTUtils.sign(users1.getName(), users1.getId());
                users1.setToken(token);
                users1.setStr("登录成功");
            }
        } else {
            users1.setStr("医生不存在");
        }
        return users1;
    }
}

第五步:持久层UsersDao

/**
 * @author gdh
 */
public interface UsersDao {
    /**
	 * 单条数据
	 */
    Users queryUsers(Users users);
}

第六步:UsersMapper.xml

<select id="queryUsers" resultMap="usersMap" parameterType="map">
    SELECT * FROM users t <include refid="where_clause" />
</select>

第七步:修改SpringMVC配置文件

<!--配置拦截器, 多个拦截器,顺序执行 -->  
<mvc:interceptors>    
    <mvc:interceptor>    
        <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
        <mvc:mapping path="/**" />
        <!-- 第一种方式:不拦截这个请求 -->
        <mvc:exclude-mapping path="/department/getDepartmentList"/>
        <mvc:exclude-mapping path="/swagger-ui.html" />
        <bean class="com.dyt.utils.CommonInterceptor">
            <!-- 第二种方式:不拦截这些请求 -->
            <property name="exceptUrls">
                <list>
                    <value>/users/Login</value>
                    <value>/users/getUsersList</value>
                    <value>/menuset/menuserList</value>
                </list>
            </property>
        </bean>
    </mvc:interceptor>  
</mvc:interceptors>  

第八步:过滤器

@Configuration
public class CommonInterceptor implements HandlerInterceptor {
	/**
	 * 在拦截器里注入一个属性List<String> exceptUrls
	 * 这里选中的是第五步中 第二种方式放行接口
	 * 如果选择第一种 下方代码删除
	 */
    private List<String> exceptUrls;

	public List<String> getExceptUrls() {
		return exceptUrls;
	}

	public void setExceptUrls(List<String> exceptUrls) {
		this.exceptUrls = exceptUrls;
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("CommonInterceptor" + "---------------" + "preHandle");
        /**
         * 这里选中的是第五步中 第二种方式放行接口  begin
         * 如果选择第一种 下方代码删除
         */
        String path =request.getRequestURI();
		if(path.startsWith(request.getContextPath())){
			path = path.substring(request.getContextPath().length(), path.length());
		}
		//系统根目录
		if (StringUtils.equals("/",path)) {
			return true;
		}
		//放行exceptUrls中配置的url
		for (String url:exceptUrls) {
			if(url.endsWith("/**")){
				if (path.startsWith(url.substring(0, url.length() - 3))) {
					return true;
				}
			} else if (path.startsWith(url)) {
				return true;
			}
		}
         /**
         * 这里选中的是第五步中 第二种方式放行接口  end
         */
        
		System.out.println("-----------------------------"+ request.getHeader("token"));
		// 如果用户已登陆放行
		if(request.getHeader("token") == null) {
			return false;
		}else
		{
			boolean verify = JWTUtils.verify(String.valueOf(request.getHeader("token")));
			if( verify == false){
				throw new RuntimeException("token出错");
			}else {
				return verify;
			}
		}
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("CommonInterceptor" + "---------------" + "postHandle");

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("CommonInterceptor" + "---------------" + "afterCompletion");
	}
}

第九步:工具类

package com.dyt.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;

public class JWTUtils {
	//过期时间设置为3分钟
	private static final long EXPIRE_TIME = 3 * 60 * 1000;
	/**
	 * token私钥
 	 */
	private static final String TOKEN_SELECT = "e96bb3ce";
	/**
	 * 生成签名
	 */
	public static String sign(String userName,Integer userId) {
		try {
			//过期时间
			Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
			System.out.println("过期时间"+date);
			//私钥加密算法
			Algorithm algorithm = Algorithm.HMAC256(TOKEN_SELECT);
			//设置头部信息
			HashMap<String,Object> map = new HashMap<String,Object>();
			map.put("typ", "JWT");
			map.put("alg", "HS256");
			//附带加密的信息
			return JWT.create()
					.withHeader(map)
					.withClaim("userName", userName)
					.withClaim("userId", userId)
					.withExpiresAt(date)
					.sign(algorithm);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
			
	}
	
	/**
	 * 	检验token是否正确
	 * @param token	密钥
	 * @return
	 */
	public static boolean verify(String token) {
		try {
			Algorithm algorithm = Algorithm.HMAC256(TOKEN_SELECT);
			JWTVerifier verifier = JWT.require(algorithm).build();
			DecodedJWT jwt = verifier.verify(token);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}

二、vue前端

第一步:安装依赖

npm install --save cookie_js

第二步:在utils下新建app.js

import cookie from "cookie_js";

//cookies名称
const adminToKen = "admin_toKen";

export function getToKen(){
    return cookie.get(adminToKen);
}

export function setToKen(token){
    return cookie.set(adminToKen,token);
}

export function removeToKen(){
    return cookie.remove(adminToKen);
}

第三步:在router下新建premint.js

import router from './index'

import {getToKen,removeToKen} from '@/utils/app'

const whiteRouter = ['/']   //indexof方法,判断数组中是否存在指定的某个对象 如果不存在,则返回-1
//路由守卫  使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆
router.beforeEach((to, from, next)=>{
    if(getToKen()){
        if(to.path === '/'){
            removeToKen();
            next();
        }else{
            next();
        }
        //console.log("存在");
    }else{
        //console.log("不存在");
        if(whiteRouter.indexOf(to.path) !== -1){ //存在
            next();
        }else{
            next('/'); //路由指向
        }
        /**
         * 1、直接进入index的时候,参数to被改变成了"/index",触发路由指向,就会跑beforeEach
         * 2、再一次next指向了login,再次发生路由指向就会跑beforeEach,参数to被改变成了"/login"
         * 3、白名单判断存在,则直接执行next(),因为没有参数,所有不会再次beforeEach
         */
    }
    //console.log(to) //进入的页面(下一个页面)
    //console.log(from)//离开之前的页面(上一个)
    //console.log(next)//执行了to里面的路由对象
  })

第四步:在main.js中引入app.js、premit.js

import './router/premit'
import {getToKen} from '@/utils/app'
import { Message } from "element-ui";
/**
 * 请求接口前,做一些数据处理(请求拦截器)
 */
 axios.interceptors.request.use(config => {
  console.log('请求拦截器')  
  config.headers.token=getToKen();
   return config;
 },
 error => {
  return Promise.reject(error);
});

/**
 * 请求接口后,返回数据进行拦截(响应拦截器)
 */
axios.interceptors.response.use(response =>{ 
  console.log('响应'+response.data.code)
  if(response.data.code== 200){
    if (response.data.code == 500 || response.data.code == 401 || response.data.code == 403) {   //接口请求成功,业务逻辑错误
      Message.error({ message: response.data.message });
      return;
    }
    if (response.data.message) {
        Message({ message: response.data.message });
    }
  }  
  else{
    if(response.data.code == 500){
      Message.error({ message: '服务器被吃了( ╯□╰ )' });
      router.replace('/');
      removeToKen();
    }
  }
  return response;
});

第五步:在login.js中引入app.js

import { setToKen } from '@/utils/app';
import { Message } from "element-ui";
//登录事件
login() {
    var data = Qs.stringify({
        'workCode': this.workCode,
        'password': this.password,
    })
    axios.post(this.GLOBAL.BASE_URL + "KFGL0601-web/users/Login", data)
        .then((res) => {
        //console.log(res);
        if (res.data.code == '200') {
            if (res.data.data.str == "登录成功") {
                this.user = res.data.data;
                // 将用户token保存到vuex中
                setToKen(res.data.data.token);
                //获取菜单
                this.getMenu();
                //提示
                Message({
                    message: "登录成功!",
                    type: "success"
                });   
            }
            else {
                this.$router.go(0);//刷新
            }
        } else {
            Message.error({ message: '登录失败' });
        }
    })
        .catch((err) => {
        console.log(err);
    });
}

版权声明:本文为qq_41096598原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。