zoukankan      html  css  js  c++  java
  • Ajax登陆,使用Spring Security缓存跳转到登陆前的链接

    Spring Security缓存的应用之登陆后跳转到登录前源地址

    什么意思?

    1. 用户访问网站,打开了一个链接:(origin url)起源链接
    2. 请求发送给服务器,服务器判断用户请求了受保护的资源。
    3. 由于用户没有登录,服务器重定向到登录页面:/login
    4. 填写表单,点击登录
    5. 浏览器将用户名密码以表单形式发送给服务器
    6. 服务器验证用户名密码。成功,进入到下一步。否则要求用户重新认证(第三步)
    7. 服务器对用户拥有的权限(角色)判定。有权限,重定向到origin url; 权限不足,返回状态码403( “禁止”)。

    从第3步,我们可以知道,用户的请求被中断了。
    用户登录成功后(第7步),会被重定向到origin url,spring security通过使用缓存的请求,使得被中断的请求能够继续执行。
    具体请看探究Spring Security缓存请求

    我这里仅讲解如何在ajax登陆后跳转到登录前的链接。

    1. 首先,如果想跳转到登陆之前的链接,我们需要拿到缓存:

    SavedRequest savedRequest = requestCache.getRequest(request, response);
    

    注意!若用户是直接访问没有权限限制的登陆页面,是不会有缓存的,也就是说savedRequest = null ,所以在使用缓存之前,我们需要做一个非null判断,也就是:

     if (savedRequest != null) {
     		// 逻辑代码
     }
    

    2. 取到登录前访问的url

    String url = savedRequest.getRedirectUrl();
    

    3. 使用hashMap建立一个对象,这是为了后续向浏览器返回json数据

     Map json = new HashMap<String, Object>();
                json.put("code", 0);
                json.put("message", "操作成功");
                json.put("url", url);
    

    可以看到这个json 对象比较简单,其中url属性是为了让浏览器端的js跳转的

    4.设置响应体编码和格式

    response.setContentType(FebsConstant.JSON_UTF8);
    

    5.向浏览器进行响应数据,这里的数据是json格式,是使用jackson工具包完成的,Maven地址:JacksonMaven地址

    response.getWriter().write(mapper.writeValueAsString(ResponseBo.ok(messsage, url)));
    

    下面是完整的Java代码:

    
    @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
            // 不管请求哪个页面,登陆成功后仅打开指定页面index
    //        redirectStrategy.sendRedirect(request, response, "/index");
    		// 获取缓存
            SavedRequest savedRequest = requestCache.getRequest(request, response);
            // 设置响应格式和编码
            response.setContentType(FebsConstant.JSON_UTF8);
            
    		// 缓存非空判断
            if (savedRequest != null) {
                // 跳转到之前引发跳转的url
                String url = savedRequest.getRedirectUrl();
                
                String messsage = "成功";
                // 准备json
                Map json = new HashMap<String, Object>();
                json.put("code", 0);
                json.put("message", "操作成功");
                json.put("url", url);
    
                Object jsons = ResponseBo.ok(messsage, url);
                response.getWriter().write(mapper.writeValueAsString(ResponseBo.ok(messsage, url)));
            } else {
            	// 这个是没有缓存,直接跳转到默认ajax默认的页面
                response.getWriter().write(mapper.writeValueAsString(ResponseBo.ok()));
            }
        }
    

    6. 前端页面Ajax代码:

        $.ajax(
            {
                type: "post",
                url: "/login",
                // 登陆表单数据序列化
                data: $form.serialize(),
                dataType: "json",
                error: function (data, type, err) {
                    if (data.responseJSON != undefined) {
                        console.log(data.responseJSON.error != undefined);
                        console.log(JSON.stringify(data.responseJSON.error));
                        $MB.n_danger("error:" + JSON.stringify(data.responseJSON.error));
                    }
                },
                success: function (data) {
                    console.log(JSON.stringify(data));
                    alert(JSON.stringify(data));
    
                    if (data.code == 0) {
                        // 如果有url,则跳转该url
                        if (data.url != undefined) {
                            $form[0].reset();
                            window.location.href = data.url;
                        } else {
                            // 重置表单的输入框内容
                            $form[0].reset();
                            window.location.href = '/index';
                            // $form.attr("action", '/index');
                        }
    
                    } else {
                        // if (r.msg !== '验证码不能为空!') reloadCode();
                        console.log(data.message);
                    }
                },
            }
        );
    

    7.不出意外的话,浏览器会收到下面的数据:

    {"code":0,"message":"操作成功"}
    

    如果你也收到了这条数据,说明已经成功了。

  • 相关阅读:
    Inno Setup执行SQL脚本的方法
    批处理命令篇--配置免安装mysql
    nsis安装包_示例脚本语法解析
    全方位掌握nsis脚本
    dos批处理知识
    mysql alter 语句用法,添加、修改、删除字段等
    .Net WebAPI 增加Swagger
    CentOS 7 Docker
    四:Ionic Framework不支持Android4.2.2的解决方法
    二:Ionic Framework支持Android开发
  • 原文地址:https://www.cnblogs.com/gobyte/p/10754273.html
Copyright © 2011-2022 走看看