vue+springboot前后端分离实现单点登录跨域问题解决方法

最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的。因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统。那就意味着做单点登录咯,至于不知道什么是单点登录的同学,建议去找一下万能的度娘。

刚接到这个需求的时候,老夫心里便不屑的认为:区区登录何足挂齿,但是,开发的过程狠狠的打了我一巴掌(火辣辣的一巴掌)。。。,所以这次必须得好好记录一下这次教训,以免以后再踩这样的坑。

我面临的第一个问题是跨域,浏览器控制台直接报CORS,以我多年开发经验,我果断在后台配置了跨域配置,代码如下:

@Configuration
public class CorsConfiguration {
 @Bean
 public WebMvcConfigurer corsConfigurer() {
  return new WebMvcConfigurerAdapter() {
   @Override
   public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
      .allowedHeaders("*")
      .allowedMethods("*")
      .allowedOrigins("*");
   }
  };
 }
}

这个配置就是允许所有mapping,所有请求头,所有请求方法,所有源。改好配置之后我果断重启项目,看效果,结果发现根本没法重定向跳转到单点登录页面,看浏览器报错是跨域导致的,我先上我登录拦截器的代码

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 //用户已经登录
 if (request.getSession().getAttribute("user") != null) {
  return true;
 }
 //从单点登录返回之后的状态,本系统还不处于登录状态
 //根据code值去获取access_token,然后再根据access_token去获取用户信息,并将用户信息存到session中
 String state = request.getParameter("state");
 String uri = getUri(request);
 if (isLoginFromSSO(state)) {
  String code = request.getParameter("code");
  Object cacheUrl = request.getSession().getAttribute(state);
  if (cacheUrl == null) {
   response.sendRedirect(uri);
   return false;
  }
  HttpUtil client = new HttpUtil();
  StringBuffer sb = new StringBuffer();
  sb.append("code=").append(code)
    .append("&grant_type=").append("authorization_code")
    .append("&client_id=").append(SSOAuth.ClientID)
    .append("&client_secret=").append(SSOAuth.ClientSecret)
    .append("&redirect_uri=").append(URLEncoder.encode((String) cacheUrl));
  String resp = client.post(SSOAuth.AccessTokenUrl, sb.toString());
  Map<String, String> map = new Gson().fromJson(resp, Map.class);
  //根据access_token去获取用户信息
  String accessToken = map.get("access_token");
  HttpUtil http = new HttpUtil();
  http.addHeader("Authorization", "Bearer " + accessToken);
  String encrypt = http.get(SSOAuth.UserUrl);
  String userinfo = decryptUserInfo(encrypt);
  //封装成user对象
  User user = new Gson().fromJson(userinfo, User.class);
  request.getSession().setAttribute("user", user);
  return true;
 }
 //跳转到单点登录界面
 state = Const._SSO_LOGIN + Const.UNDERLINE + RandomUtil.getUUID();
 request.getSession().setAttribute(state, uri);
 String redirectUrl = buildAuthCodeUrl(uri, state);
 response.sendRedirect(redirectUrl);
 return false;
}

后面把前端vue请求后台的登录接口方式直接用

window.location.href=this.$api.config.baseUrl+"/system/user/login"

之后前端访问系统,可以直接跳转到单点登录页面。但是当我输完账号和密码点击登录后回跳到系统,发现所有的请求数据接口都无法正常访问,debug发现所有的请求都没带用户信息,被拦截器识别为未登录,所有请求无法通过。

为什么我明明登录了呀,拦截器也设置了用户信息到session啊,怎么cookies那就没了呢?再次发起请求,发现每次请求的JsessionId都不一样,查了很多资料,发现是需要在前端加一个允许带认证信息的配置

axios.defaults.withCredentials=true;

后台也需要做一个相应的配置allowCredentials(true);

@Bean
public WebMvcConfigurer corsConfigurer() {
 return new WebMvcConfigurerAdapter() {
  @Override
  public void addCorsMappings(CorsRegistry registry) {
   registry.addMapping("/**")
     .allowedHeaders("*")
     .allowedMethods("*")
     .allowedOrigins("*").allowCredentials(true);
  }
 };
}

加完这个配置之后,重新执行一遍操作流程,发现登录之后能正常跳转到系统,页面数据也展示正常。

正当我以为大功告成的时候,突然点到一个页面又无法正常显示数据,好纳闷啊,赶紧F12,发现一个之前没见过的请求方式,OPTIONS请求,原来这个请求方式明明是POST呀,怎么就变成了OPTIONS了呢?于是我有点了其他几个POST的请求,发现都变成了OPTIONS请求,一脸懵逼的我赶紧查了一下OPTIONS请求的资料,网上说OPTIONS请求叫做“预检查请求”,就是在你的正式请求执行之前,浏览器会先发起预检查请求,预检查请求通过了,才能执行正式请求。看完恍然大悟,原来OPTIONS被拦截了,所以没法再执行我的POST的请求啊,那我直接让预检查请求通过就好了。只要在拦截器中加一个这个判断就好了

//option预检查,直接通过请求
if ("OPTIONS".equals(request.getMethod())){
 return true;
}

这样拦截器发现请求是预检查请求就直接通过,就可以执行接下来的POST的请求了。

总结

以上所述是小编给大家介绍的vue+springboot前后端分离实现单点登录跨域问题解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

您可能感兴趣的文章:

  • 基于vue-resource jsonp跨域问题的解决方法
  • vue.js使用代理和使用Nginx来解决跨域的问题
  • vue-cli开发时,关于ajax跨域的解决方法(推荐)
  • 基于VUE移动音乐WEBAPP跨域请求失败的解决方法
  • Nginx 解决WebApi跨域二次请求以及Vue单页面的问题
  • vue解决跨域路由冲突问题思路解析
  • vue2.0设置proxyTable使用axios进行跨域请求的方法
  • vue+Java后端进行调试时解决跨域问题的方式
  • vue使用axios跨域请求数据问题详解
  • vue跨域解决方法
  • vue几个常用跨域处理方式介绍
时间: 2018-01-29

vue使用axios跨域请求数据问题详解

axios默认是没有jsonp 跨域请求的方法的.一般来说流行的做法是将跨域放在后台来解决,也就是后台开发人员添加跨域头信息. 例如java中的 header,response.setHeader("Access-Control-Allow-Origin", www.allow-domain.com) 但是很多时候,后台出于一些原因不想修改或者已经写好jsonp的接口需要适应不同平台,此时,前端就可以单独引入依赖解决该问题了. 引入依赖 cnpm install jsonp 导入到vu

vue+Java后端进行调试时解决跨域问题的方式

今天在开发过程中遇到一个问题,拿到了一套vue代码,计划对这套代码的部分样式进行调整,Java后端代码已经写好并且部署到了线上.这时命令行运行vue项目时访问会受限,取不下数据来,遇到了跨域访问失败的问题,这时可以怎么做呢? 首先,要了解什么叫跨域访问? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制. 所谓同源是指,域名,协议,端口均相同,举个例子: http://www.123.com/index.html 调用 http

vue.js使用代理和使用Nginx来解决跨域的问题

使用Nginx 反向代理解决跨域问题(vue.js使用代理去掉vue.js因为跨域而触发的options请求) 我们的项目还是需要node.js作为容器的 一.Windows 下安装Nginx (官网下载稳定版http://nginx.org/en/download.html) 二.修改config里的nginx.conf文件的server server { listen 8899;// 你的端口 server_name localhost; root C:/ZOBSF_F/dist;//你打包

基于VUE移动音乐WEBAPP跨域请求失败的解决方法

在学习一位vue大牛的课程<VUE2.0移动端音乐App开发>时,由于vue的版本原因遇到了一些问题 这是其中之一,花费了很多的时间去解决 虽然搞定了这个问题,但是很多东西理解也不是很到位,下面详细说: 系统windows,vue版本2.9.1 项目结构如下: 这里就知道版本差异了,我没有dev-server这个文件,按照黄大牛的配置会报404的错误,错误具体我就不贴了 直接上解决办法 首先在config目录下配置index.js文件如下 然后在webpack.dev.conf中配置如下 当然

vue2.0设置proxyTable使用axios进行跨域请求的方法

这里请求的是知乎日报的api,由@izzyleung这位大神提供的,这是github地址. 在vue-cli构建的项目中先安装axios npm install axios -S 这里暂不考虑用vuex封装的方式,只讲在当前组件中直接使用. 先在<script>中引入 用prototype将axios添加为vue原生的属性,$ajax相当于axios的别名. 然后在要调用的方法或是钩子中请求,$ajax就是上面注册的axios,如果想直接用axios不想设置prototype也可以直接按官方的

Nginx 解决WebApi跨域二次请求以及Vue单页面的问题

一.前言 由于项目是前后端分离,API接口与Web前端 部署在不同站点当中,因此在前文当中WebApi Ajax 跨域请求解决方法(CORS实现)使用跨域处理方式处理而不用Jsonp的方式. 但是在一段时间后,发现一个很奇怪的问题,每次前端发起请求的时候,通过浏览器的开发者工具都能看到在Network下同一个url有两条请求,第一条请求的Method为OPTIONS,第二条请求的Method才是真正的Get或者Post,并且,第一条请求无数据返回,第二条请求才返回正常的数据. 二.原因 第一个O

vue跨域解决方法

vue项目中,前端与后台进行数据请求或者提交的时候,如果后台没有设置跨域,前端本地调试代码的时候就会报"No 'Access-Control-Allow-Origin' header is present on the requested resource." 这种跨域错误. 要想本地正常的调试,解决的办法有三个: 一.后台更改header header('Access-Control-Allow-Origin:*');//允许所有来源访问 header('Access-Control

vue几个常用跨域处理方式介绍

设置express代理请求 在基于vue-cli的项目中,在开发环境配置(config/dev.env.js)中设置代理,能够将所有/apidomain开头的请求都通过npm run dev启动的express服务器重定向到目标接口 官方文档:https://vuejs-templates.github.io/webpack/proxy.html proxyTable: { '/apidomain':{ target:'http://localhost:prot',//或ip或域名. chang

基于vue-resource jsonp跨域问题的解决方法

最近在学习vue.js 碰到个ajax跨域请求的问题,之前知道可以用jsonp解决,但是一直没实践过,这次用发现里面好多问题,所以现在记录下来,希望可以给刚接触使用jsonp的同学一点帮助! 关于什么是jsonp,以及为什么要用jsonp我就不多说了,不明白的同学自行百度一下. 我们先来说一下jQuery里面的jsonp请求,这搞懂了 vue-resource 里面的jsonp就容易明白了. 这里我以json数据为例,首先我们通过 $.get可以直接得到一个我们想要的对象,但是用 jsonp 就

vue-cli开发时,关于ajax跨域的解决方法(推荐)

目的:使用vue-cli构建的项目,在开发时,想要访问后台接口获取数据,这时就会出现跨域问题. 在config/index.js中进行如下配置 [即在进行ajax请求时,地址中任何以/api开头的请求地址都被解析为目标地址,target就是你想要的后台接口地址] proxyTable: { '/api': { target: 'https://188.188.18.8', changeOrigin: true, pathRewrite: { '^/api': " } } } "` vu

vue解决跨域路由冲突问题思路解析

vue 简介 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架. Vue 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. Vue 学习起来非常简单,本教程基于 Vue 2.1.8 版本测试. 当我们在路由里面配置成以下代理可以解决跨域问题 proxyTable: { '/goods/*': { target: 'http://localhost:3000' }, '/users/*

如何在vue里面优雅的解决跨域(路由冲突问题)

如何在vue里面优雅的解决跨域,路由冲突问题 当我们在路由里面配置成以下代理可以解决跨域问题 proxyTable: { '/goods/*': { target: 'http://localhost:3000' }, '/users/*': { target: 'http://localhost:3000' } }, 这种配置方式在一定程度上解决了跨域问题,但是会带来一些问题, 比如我们的vue 路由 也命名为 goods,这时候就会产生了冲突, 如果项目中接口很多,都在这里配置是很麻烦的,也

浅析JSONP解决Ajax跨域访问问题的思路详解

前几天,工作上有一新需求,需要前端web页面异步调用后台的Webservice方法返回信息.实现方法有多种,本例采用jQuery+Ajax,完成后,在本地调试了一切ok,但是部署到服务器上以后就出现问题了,后台服务调用没有响应,怎么回事?代码没怎么改动,唯一修改的地方就是jQuery的ajax方法中的url地址.难道是这里的问题,经过检查和调试,发现原来是同源策略在作怪,我们知道,JavaScript或jQuery是在Web前端开发中经常使用的动态脚本技术.在JavaScript中,有一个很重要

vue中axios解决跨域问题和拦截器的使用方法

vue中axios不支持vue.use()方式声明使用. 所以有两种方法可以解决这点: 第一种: 在main.js中引入axios,然后将其设置为vue原型链上的属性,这样在组件中就可以直接 this.axios使用了 import axios from 'axios'; Vue.prototype.axios=axios; components: this.axios({ url:"a.xxx", method:'post', data:{ id:3, name:'jack' } }

vue打包使用Nginx代理解决跨域问题

vue 在开发环境,涉及跨域,就在本地配置了代理,但是部署到服务器上,就不行了. 解决方法有一下几种 服务器端配置CORS 用nginx反向代理,和访问本地服务器是一样的 可以修改成正式线上的地址,再build 推荐 使用nginx配置反向代理,这样就可以在前端彻底解决跨域问题. vue index.js文件源码 'use strict' // Template version: 1.2.7 // see http://vuejs-templates.github.io/webpack for

解决前后端分离 vue+springboot 跨域 session+cookie失效问题

环境: 前端 vue ip地址:192.168.1.205 后端 springboot2.0 ip地址:192.168.1.217 主要开发后端. 问题: 首先登陆成功时将用户存在session中,后续请求在将用户从session中取出检查.后续请求取出的用户都为null. 解决过程: 首先发现sessionID不一致,导致每一次都是新的会话,当然不可能存在用户了.然后发现cookie浏览器不能自动保存,服务器响应set-cookie了 搜索问题,发现跨域,服务器响应的setCookie浏览器无

vue项目打包后怎样优雅的解决跨域

前言 在使用vue.js开发前端项目时,再结合webpack搞起各种依赖.各种插件进行开发,无疑给前端开发带来了很多便捷,就在解决跨域这个问题上,相信众多用vue.js的前端同僚们同我一样尝到了甜头,开发环境全靠proxyTable一通配置简直不要太酸爽.还不明所以然的新手们可能还没搞清我说的是什么,就是下面这几行配置: proxyTable: { '/api': { target: 'http://113.113.113.113:5000', //假的接口地址哈 changeOrigin: t

Vue proxyTable配置多个接口地址,解决跨域的问题

最开始的时候,因为请求后台出现跨域问题. 查找资料配置proxyTable,解决跨域问题.如下图所示: axios请求页面: this.$axios.post('/api/weblogin/login',data).then(res=>{ console.log(res) }) 后面遇到需要连接不同的接口域名,我在proxyTable里增加了一个apiGas.axios请求存在获取得到api但是不能获取apiGas(提示请求资源不存在). proxyTable: { '/api': { targ