springboot+vue+redis项目的前端+后端接口校验

本次实验是基于前后端分离项目:springboot+vue+redis

接口校验时机:

​ 后端:拦截所有请求,放行登录请求、请求头中包含token(用户名和密码正确时,回生成一个令牌,用来放心别的请求)的请求。

​ 前端:拦截所有请求,放行登录请求、对非登录请求{如果,用户已经登录,则给请求头中添加token,如果用户未登录,跳到登陆页面}

1 后端实现

1.1 集成redis

https://blog.csdn.net/qq_43644923/article/details/117607257

1.2 书写WebAppConfigurer配置类

第17行:拦截所有请求

第18行:放行登录请求,

第16行:其他所有的请求经过loginINterceptor

@Configuration
public class WebAppConfigurer extends WebMvcConfigurationSupport {

    @Resource
    LoginInterceptor loginInterceptor;

    /**
     * 注册拦截器
     *
     * @param registry
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        System.out.println("addInterceptors");
        super.addInterceptors(registry);
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login")
            ;

    }


}

1.3 LoginInterceptor

① return false表示拦截,不向下执行

② return true表示放行

③ 本类的作用:对经过本类的请求,放行login(登录)、放行OPTIONS请求(post请求的第一次请求。对于post请求,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)?如果这里说的不对,请大家不吝赐教)、拦截剩余所有请求,判断请求头中是否包含token,以及如果包含,该token是否在redis数据库中也同样存在

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Resource
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setContentType("text/html; charset=UTF-8");
        String url = request.getRequestURI();
        // System.out.println("url: "+url);

        // 获取请求头中的token
        String headerToken = request.getHeader("token");

        // 规定,请求错误时,返回数据,
        Result headerError = Result.error("请求头错误,请登录");
        Result tokenError = Result.error("token过期,请重新登录");


        //  如果进行登录提交,放行
        if (url.indexOf("login") >= 0) {
            return true;
        }

        //  如果是option请求,放行
        //  option请求是post请求的第一次请求
        if(request.getMethod().equals("OPTIONS")){
            return true;
        }

        // 判断请求头中是否含有token
        // 没有token
        if(headerToken==null || headerToken.length()==0){
            response.getWriter().write(JSON.toJSONString(headerError));
            return false;
        }else {
            // 含有token,且redis中存在该token
            // return true;
            Boolean isExist = redisTemplate.opsForSet().isMember("token", headerToken);
            
            log.info(isExist.toString());
          
            return isExist;
        }
          //return false表示拦截,不向下执行
          //return true表示放行
    }
}

2 前端实现

前端是一个vue项目,集成了axios组件、路由组件

2.1 创建request.js,封装前端的请求,添加请求头

这里要用到axios,如果没有安装axios组件,请先安装axios组件

15行:判断用户是否登录。这一步是从localStorage中获取loginUser,该数据是我在登录时向浏览器存储的用户信息

16行:判断请求路径是否为,“/”,在我的代码里对应的是登录请求

17行:解构在浏览器存储的用户信息,获得token

20行:给所有到20行的请求(用户已登录且,当前请求不是登录请求)添加请求头[“token”,token],key-value格式

import axios from 'axios'

// 创建axios实例
const service = axios.create({
    baseURL: 'http://8.141.49.4:8010', // api的base_url
    timeout: 100000 // 请求超时时间
})

//请求拦截器
service.interceptors.request.use(
    (config) => {
        console.log("请求拦截");
        let pathname = location.pathname;

        if(localStorage.getItem("loginUser")){
            if(pathname != '/'){
                let {token} = JSON.parse(localStorage.getItem("loginUser"));
                console.log("token")
                console.log(token)
                config.headers.common['token'] = token;
            }
        }
        console.log(config);
        return config;
    },
    (error) => {
        return Promise.reject(error);
    })

export default service

2.2 撰写/router/index.js

如果使用vue-cli安装了路由组件,那么在项目的/src/router目录下会有一个index.js文件。用来管理前端的路由

需要注意的是:这段代码的核心在17-19行与38行的组合,给一个路由添加17-19行实例代码表示该路由需要用户登陆后才会放行,如果未登录,则会跳转到登录页。

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [

    {
        path: '/',
        name: 'Login',
        component: () => import('@/components/commons/Login')
    },
    
    {
        path: '/home',
        name: 'Container',
        meta: {
            requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
        }
        component: () => import('../layout/Container')
    },

    {
        path: '*',
        name: 'error',
        component: () => import('../components/commons/Error')
    },
]

const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
})
router.beforeEach((to, from, next) => {
    console.log("beforeEach")
    // 判断该路由是否需要登录权限
    if (to.meta.requireAuth) {
        // 判断用户是否登录
        if (localStorage.getItem("loginUser")) {
            next();
        }
        else {
            next({
                path: '/',
                // 将跳转的路由path作为参数,登录成功后跳转到该路由
                query: {redirect: to.fullPath}
            })
        }
    }
    else {
        next();
    }
})

export default router

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值