SpringBoot的跨域設(shè)置實(shí)現(xiàn)Api認(rèn)證token獲取

Spring Boot的跨域是一個(gè)老生常談的問(wèn)題,網(wǎng)上提供的方法主要是三種:
1.編寫CorsFilter實(shí)現(xiàn)跨域
2.覆寫WebMvcConfigurer
3.使用注解(@CrossOrigin)
這三種可能都能實(shí)現(xiàn)跨域,但前提是只是單純的跨域。我的業(yè)務(wù)場(chǎng)景是,對(duì)外開放API接口,請(qǐng)求方必須在頭部攜帶發(fā)放的token,在接口上加上過(guò)濾器,解析token是否合法,這種情況下,上面的3個(gè)方法都存在一定的問(wèn)題,方法本身沒錯(cuò),但錯(cuò)在網(wǎng)上大部分教程都應(yīng)該不是針對(duì)token驗(yàn)證的,導(dǎo)致一些屬性未在代碼中設(shè)置,就會(huì)產(chǎn)生很大的問(wèn)題。
下面我就介紹方法2,在解決我這個(gè)業(yè)務(wù)場(chǎng)景的時(shí)候出現(xiàn)的問(wèn)題,及解決方法。

1 我的請(qǐng)求

function testClick(){
        $.ajax(
            {
                url:"http://localhost:9999/questionapi/getEdition",
                type:'GET',
                beforeSend: function(xhr){
                    xhr.setRequestHeader('Authorization', 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNTg1MTQxOTkxLCJpYXQiOjE1ODQ1MzcxOTF9.EPGyOtbwNfwg7CwN0mI15jBiMWGFCho6BvowtyVY0uSI8jMJVDwhcRRCJIhjUSCDExBn-weVg0z20b-gXVvdCQ');
                },
                success:function(result){
                    $("#div1").html(result);
        }});
    }

2 我的WebMvcConfig

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    private final static Logger logger = LoggerFactory.getLogger(CorsConfig.class);
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        logger.info("允許跨域訪問(wèn)");
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*");
    }
}

基本網(wǎng)上的教程都是上面這個(gè)樣子,但是這種情況下,我在攔截器中獲取到的header參數(shù)就是下面這個(gè)樣子:

host:localhost:9999
connection:keep-alive
accept:*/*
access-control-request-method:POST
access-control-request-headers:authorization
origin:http://localhost:8787
sec-fetch-mode:cors
sec-fetch-site:same-site
referer:http://localhost:8787/test/index.html
user-agent:Mozilla/5.0 & #40;Windows NT 10.0; Win64; x64& #41; AppleWebKit/537.36 & #40;KHTML, like Gecko& #41; Chrome/80.0.3987.132 Safari/537.36
accept-encoding:gzip, deflate, br
accept-language:zh-CN,zh;q=0.9,en;q=0.8

很大的問(wèn)題,我期待authorization是作為header中的一個(gè)key值,但是它變成了“access-control-request-headers”這個(gè)key對(duì)應(yīng)的值。而且還有一個(gè)很怪的現(xiàn)象,當(dāng)我攔截器不再對(duì)API請(qǐng)求進(jìn)行攔截,在API接口中,從header獲取參數(shù)就是非常正常的下面這個(gè)樣子:

host:localhost:9999
connection:keep-alive
content-length:0
accept:*/*
sec-fetch-dest:empty
authorization:Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNTg1MTQxOTkxLCJpYXQiOjE1ODQ1MzcxOTF9.EPGyOtbwNfwg7CwN0mI15jBiMWGFCho6BvowtyVY0uSI8jMJVDwhcRRCJIhjUSCDExBn-weVg0z20b-gXVvdCQ
user-agent:Mozilla/5.0 & #40;Windows NT 10.0; Win64; x64& #41; AppleWebKit/537.36 & #40;KHTML, like Gecko& #41; Chrome/80.0.3987.132 Safari/537.36
origin:http://localhost:8787
sec-fetch-site:same-site
sec-fetch-mode:cors
referer:http://localhost:8787/test/index.html
accept-encoding:gzip, deflate, br
accept-language:zh-CN,zh;q=0.9,en;q=0.8

怎么回事?其實(shí)我到現(xiàn)在也沒搞清楚為什么,我也不能單獨(dú)為某個(gè)api讓它繞過(guò)過(guò)濾器,雖然可行但是這種代碼就非常惡心。搜了好多資料,不得不吐槽國(guó)內(nèi)的解答,真的沒什么用,總算找到了解決方法。

3 我的解決方法

修改你的WebMvcConfig為下面這種樣子:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    private final static Logger logger = LoggerFactory.getLogger(CorsConfig.class);
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        logger.info("允許跨域訪問(wèn)");
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .exposedHeaders("Authorization","X-Requested-With","accept","Origin","Access-Control-Request-Method","Access-Control-Request-Headers")//如果它不設(shè)置預(yù)期的請(qǐng)求頭部參數(shù)key值的話,ajax請(qǐng)求頭部就沒辦法正確解析,也就是token解析不出來(lái)
                .allowCredentials(true);//如果它不設(shè)置為true的話,ajax請(qǐng)求頭部就沒辦法正確解析,也就是token解析不出來(lái)
    }
}

看清楚區(qū)別,增加了exposedHeaders和allowCredentials兩個(gè)配置,exposedHeaders是為了告訴過(guò)濾器你希望的頭部參數(shù)有哪些,allowCredentials是為了允許你可以傳送帶認(rèn)證參數(shù)的頭部信息。這樣做了以后,你在攔截器里面獲取到的頭部參數(shù)就是你希望的樣子了。

雖然是個(gè)小小的修改,但真的花了好久的時(shí)間才解決掉,記錄一下,希望能對(duì)大家有幫助。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容