redis+token实现登录校验,前后端分离,及解跨域问题的4种方法

本文介绍了在前后端分离的环境中处理跨域问题的几种方法,包括使用自定义Filter设置请求头,编写拦截器验证登录状态,以及通过SpringMVC的CORS配置和注解进行局部跨域配置。同时,文中提到了登录过程中token的生成与存储,并强调了在allowCredentials为true时,allowedOrigins不应设置为*。
摘要由CSDN通过智能技术生成

 

目录

一、使用自定义filter实现跨域

1、客户端向服务端发送请求

2、服务端做登录验证了,并生成登路用户对应的token,保存到redis

3、响应(报错)-----跨域问题

4、解决跨域问题--------服务器端添加过滤器,设置请求头

5、重新登录正确响应

6、客户端登redis录后访问页面,需要经过拦截器验证登录状态

7、编写拦截器

二、在任意配置类,返回一个 新的 CorsFIlter Bean 

三、使用注解 (局部跨域)

四、手动设置响应头(局部跨域)


前提:前后端分离

一、使用自定义filter实现跨域

1、客户端向服务端发送请求

使用ajax实现登录

<script>
        function login(){
            var userCode = $("#userCode").val();
            var userPassword = $("#userPassword").val();
            $.ajax({
                url:"http://localhost:9000/login.do",
                type:"post",
                data: "userCode="+userCode+"&userPassword="+userPassword,
                dataType: "text",
                success: function (result){
                    if(result!=null && result!=""){
                        alert("登录成功")
                        localStorage.token=result
                        window.location.href="view/frame.html";
                    }else {
                        alert("登录失败")
                    }
                }
            })
        }
    </script>

2、服务端做登录验证了,并生成登路用户对应的token,保存到redis

@RequestMapping ("/login.do")
    public String login(String userCode, String userPassword, Model model){
        User user = userService.login(userCode,userPassword);
        if(user!=null){
            //使用UUID生成token
            String token = UUID.randomUUID().toString().replace("-","");
            //把token保存到redis中,时效1小时
            RedisTools.setEx(token,user.getUserName(),1,TimeUnit.HOURS);
            System.out.println(token);
            return token;
        }
        return "";
    }

3、响应(报错)-----跨域问题

4、解决跨域问题--------服务器端添加过滤器,设置请求头

@Component
@WebFilter("/**")
public class MyCorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        //设置字符集编码
        HttpServletRequest request = (HttpServletRequest) req;
        request.setCharacterEncoding("UTF-8");
        HttpServletResponse response = (HttpServletResponse) res;
        response.setCharacterEncoding("UTF-8");
        //"*":允许任何请求源访问,实际生产环境按公司要求
        response.setHeader("Access-Control-Allow-Origin", "*");
        //设置请求方式
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        //最大时间
        response.setHeader("Access-Control-Max-Age", "3600");
        //response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        //添加自定义的请求头信息,"*"任何自定义请求头信息
        response.setHeader("Access-Control-Allow-Headers", "*");
        System.out.println("*********************************过滤器被使用**************************");
        //放行
        chain.doFilter(req, res);
    }
}

5、重新登录正确响应

6、客户端登redis录后访问页面,需要经过拦截器验证登录状态

客户端登录发送请求时,将token放入请求头中: headers:{"token":localStorage.token},

<script>
        function getUserList(){
            $.ajax({
                url: "http://localhost:9000/user/list.do",
                type:"get",
                headers:{"token":localStorage.token},
                dataType:"text",
                success:function (result){
                    alert(result)
                }
            })
        }
    </script>

7、编写拦截器

从请求头中获取token的值,判断是否不为空,且token这个key存在于rdeis中,若存在则放行,反之拦截

public class SysIntercerptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if(StringUtil.isNullOrEmpty(token) || !RedisTools.hasKey(token)){
            System.out.println("登录已过期");
            PrintWriter out = response.getWriter();
            out.println("alert('登录已过期,请重新登录')");
            return false;
        }
        return true;
    }
}

前端

 后端

  

二、在任意配置类,返回一个 新的 CorsFIlter Bean 

@Configuration
public class CorsConfig  implements WebMvcConfigurer {
    //方式1
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 设置允许跨域的路由
        registry.addMapping("/**")
                //是否发送Cookie是否允许证书(cookies)
                .allowCredentials(true)
                // 设置允许跨域请求的域名------------修改此行//放行哪些原始域
                //.allowedOrigins("*")
                .allowedOriginPatterns("*")
                // 设置允许的方法
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                .allowedHeaders("*")
                .exposedHeaders("*");

    }
        //方式2
//    @Override
//    public void addCorsMappings(CorsRegistry registry){
//        registry.addMapping("/*/**")
//                .allowedHeaders("*")
//                .allowedMethods("*")
//                .maxAge(1800)
//                .allowedOrigins("*");
//    }
    
}

    When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead
当allowCredentials为true时,allowedOrigins不能包含特殊值“*”,因为不能在“Access Control Allow Origin”响应标头上设置该值。要允许一组来源的凭据,请显式列出它们或考虑改“allowedOriginPatterns”
 /*将红框中的.allowedOrigins("*")替换为.allowedOriginPatterns("*")即可*/

三、使用注解 (局部跨域)

@CrossOrigin(origins = "*")
 

四、手动设置响应头(局部跨域)

使用 HttpServletResponse 对象添加响应头(Access-Control-Allow-Origin)来授权原始域,这里 Origin的值也可以设置为 “*”,表示全部放行。

@RequestMapping("/index")
public String index(HttpServletResponse response) {
    response.addHeader("Access-Allow-Control-Origin","*");
    return "index";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值