springsecurity4+jwt和vue.js+axios跨域问题

        后端用springboot + spring security4 + JWT,前端用vue.js+axios发送post老是请求失败,在网上查了各种文章,问题最终解决。

      1,首先在继承于WebSecurityConfigurerAdapter类的子类中(我的是WebSecurityConfig)设置cors属性。

package com.example.securitydemoserver.config.security

import com.example.securitydemoserver.config.jwt.JWTAuthenticationFilter
import com.example.securitydemoserver.config.jwt.JWTAuthorizationFilter
import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.builders.WebSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import javax.servlet.http.HttpServletResponse
import org.apache.commons.logging.LogFactory
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.http.HttpMethod
import org.springframework.security.config.http.SessionCreationPolicy

@Configuration
@EnableWebSecurity//开启spring security 功能
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)//开启spring security 注解,如@PreAuthorize,@PreFilter等
class WebSecurityConfig: WebSecurityConfigurerAdapter() {
    val objectMapper= ObjectMapper();
    val logger=LogFactory.getLog(WebSecurityConfig::class.java)
    @Autowired
    lateinit var myUserDetailsService: MyUserDetailsService

    override fun configure(http: HttpSecurity) {
        http
                //开启模拟请求,比如API POST测试工具的测试,不开启时,API POST为报403错误
                .csrf().disable()
                //开启跨域访问.cors()**********************我在这里*****************
                .cors()
                .and()
                .httpBasic()
                //未登录时,进行json格式的提示,很喜欢这种写法,不用单独写一个又一个的类
                .authenticationEntryPoint { request, response, authException ->
                        response.setContentType("application/json;charset=utf-8");
                        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                        var out = response.getWriter();
                        var map = mutableMapOf<String, Any>();
                        map.put("code", 403);
                        map.put("message", "未登录");
                        out.write(objectMapper.writeValueAsString(map));
                        out.flush();
                        out.close();
                }
                .and()
                    .authorizeRequests().anyRequest().authenticated()
                .and()
                    .addFilter(JWTAuthenticationFilter(authenticationManager()))
                    .addFilter(JWTAuthorizationFilter(authenticationManager()))
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    }
    /*身份认证*/
    override fun configure(auth: AuthenticationManagerBuilder) {
        auth.userDetailsService(myUserDetailsService).passwordEncoder(BCryptPasswordEncoder())
    }

    override fun configure(web: WebSecurity) {
       web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**")
    }
    /*必须要有这个bean告诉spring密码的加密方式*/
    @Bean
    fun passwordEncoder() = BCryptPasswordEncoder()
}

若不设置cors或设置为cors().disable()则报错

Access to XMLHttpRequest at 'http://localhost:8090/api/login' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

2,添加跨域配置

package com.example.securitydemoserver.config

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
import org.springframework.web.filter.CorsFilter
/**
 * springboot + security +jwt跨域请求配置*/
@Configuration
class CorsConfig {
    private fun buildConfig(): CorsConfiguration{
        var corsConfiguration = CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*")
        corsConfiguration.addAllowedHeader("*")
        corsConfiguration.addAllowedMethod("*")
        corsConfiguration.allowCredentials
        return corsConfiguration
    }
    @Bean
    fun corsFilter(): CorsFilter {
        var source = UrlBasedCorsConfigurationSource();
        //可以访问的地址
        source.registerCorsConfiguration("/**",buildConfig())
        return CorsFilter(source)
    }
}

若无以上配置则报错:Access to XMLHttpRequest at 'http://localhost:8090/api/login' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.3

3,接着就需要在前端的访问加上请求头。

方法一:
const instance = axios.create({
    baseURL: 'http://localhost:8090',
    headers: {
        'Access-Control-Allow-Origin': '*'
    }
});
方法二:
const instance = axios.create({
    baseURL: 'http://localhost:8090',
});
instance.interceptors.request.use((config) => {
    config.headers['X-Client'] = _.get(store, 'state.app.code');
    config.headers['Access-Control-Allow-Origin'] = '*'
    return config;
  });

如果框架是springboot+security4+JWT的话基本就没啥子问题了,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值