


How to solve the single sign-on cross-domain problem by separating the front-end and back-end of vue+springboot
The code is as follows:
@Configuration public class CorsConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*"); } }; } }
This configuration allows all mapping, all request headers, all request methods, and all sources. After changing the configuration, I decisively restarted the project to see the effect. I found that there was no way to redirect to the single sign-in page. Seeing that the browser error was caused by cross-domain, I first uploaded the code of my login interceptor
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; }
Later, the front-end vue requests the back-end login interface directly using
window.location.href=this.$api.config.baseUrl+"/system/user/login"
and then the front-end accesses the system and can jump directly to the single sign-in page. But when I entered my account and password and clicked to log in, I jumped back to the system and found that all request data interfaces could not be accessed normally. Debug found that all requests did not carry user information and were recognized by the interceptor as not logged in, so all requests could not pass. .
Why am I clearly logged in and the interceptor also sets user information to the session? Why are the cookies gone? I initiated a request again and found that the JsessionId of each request was different. I checked a lot of information and found that I needed to add a configuration that allows authentication information to be added to the front end.
axios.defaults.withCredentials=true;
A corresponding configuration also needs to be made in the backend allowCredentials(true );
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*").allowCredentials(true); } }; }
After adding this configuration, I re-executed the operation process and found that after logging in, I can jump to the system normally and the page data is also displayed normally.
Just when I thought I was done, I suddenly clicked on a page and the data could not be displayed normally. I was so puzzled. I quickly F12 and found a request method I had never seen before, the OPTIONS request. It turns out that this request method is obviously POST, why did it become OPTIONS? So I ordered several other POST requests and found that they all turned into OPTIONS requests. I was confused and quickly checked the information of OPTIONS requests. The Internet said that OPTIONS requests are called "pre-check requests", which means that in your formal Before the request is executed, the browser will first initiate a pre-check request. Only after the pre-check request passes can the formal request be executed. After reading it, I suddenly realized that OPTIONS was intercepted, so I could no longer execute my POST request. Then I just let the pre-check request pass. Just add this judgment to the interceptor
//option预检查,直接通过请求 if ("OPTIONS".equals(request.getMethod())){ return true; }
In this way, if the interceptor finds that the request is a pre-check request, it will pass it directly, and the next POST request can be executed.
The above is the detailed content of How to solve the single sign-on cross-domain problem by separating the front-end and back-end of vue+springboot. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Using Bootstrap in Vue.js is divided into five steps: Install Bootstrap. Import Bootstrap in main.js. Use the Bootstrap component directly in the template. Optional: Custom style. Optional: Use plug-ins.

You can add a function to the Vue button by binding the button in the HTML template to a method. Define the method and write function logic in the Vue instance.

There are three ways to refer to JS files in Vue.js: directly specify the path using the <script> tag;; dynamic import using the mounted() lifecycle hook; and importing through the Vuex state management library.

The watch option in Vue.js allows developers to listen for changes in specific data. When the data changes, watch triggers a callback function to perform update views or other tasks. Its configuration options include immediate, which specifies whether to execute a callback immediately, and deep, which specifies whether to recursively listen to changes to objects or arrays.

Vue multi-page development is a way to build applications using the Vue.js framework, where the application is divided into separate pages: Code Maintenance: Splitting the application into multiple pages can make the code easier to manage and maintain. Modularity: Each page can be used as a separate module for easy reuse and replacement. Simple routing: Navigation between pages can be managed through simple routing configuration. SEO Optimization: Each page has its own URL, which helps SEO.

Vue.js has four methods to return to the previous page: $router.go(-1)$router.back() uses <router-link to="/" component window.history.back(), and the method selection depends on the scene.

There are three common methods for Vue.js to traverse arrays and objects: the v-for directive is used to traverse each element and render templates; the v-bind directive can be used with v-for to dynamically set attribute values for each element; and the .map method can convert array elements into new arrays.

You can query the Vue version by using Vue Devtools to view the Vue tab in the browser's console. Use npm to run the "npm list -g vue" command. Find the Vue item in the "dependencies" object of the package.json file. For Vue CLI projects, run the "vue --version" command. Check the version information in the <script> tag in the HTML file that refers to the Vue file.
