Spring Boot and OAuth2 Tutorials 的一個問題

https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_click

最近在做這個Tutorial, 基本是OAuth2典型的登錄流程:
1.用戶在自己網站的網頁上點擊“Login Using FaceBook”後跳轉到FaceBook(OAuth2 Auth Server)進行認證
2.到Auth Server的授權頁面進行授權
3.到自己網站的某URL觸發AccessToken的Exchange
4.獲取AccessToken成功後回到初始頁面。

因爲有自己的技術棧,所以並沒有採用官方的AngularJS做前端,我就簡單的用了Fetch+JQuery,結果出現以下問題:
OAuth2 Auth Server(我用的自己寫的server,不是FB)登錄成功後,瀏覽器並沒有跳轉回localhost/頁面,而是跳轉到了localhost/user的頁面,儘管登錄成功了,但是這個landing page是有問題的。

跟了一下源碼,記錄幾個知識點:
1.在OAuth2SsoProperties類中定義了DEFAULT_LOGIN_PATH,爲"/login",這個URL用於步驟3,是負責跟Auth server交換Token的URL,OAuth2流程中有個Return URI的概念,就是Auth Server在認證成功後要把你重定向到哪裏的URL。

2.在/login的業務邏輯做完之後,該把用戶重定向到哪裏呢? 當然應該重定向到用戶"上一次訪問"的頁面。這個"上一次訪問"的頁面是怎麼定義的?是在ExceptionTranslationFilter(這個Filter的功能請自己補充下知識)中觸發的,最終調用了HttpSessionRequestCache.saveRequest(),儲存了一個requestCache。也就是說,如果你訪問的頁面不是一個受到保護的頁面,Spring是不會保存這個request Cache的。 當然了,Spring也提供了其他重定向策略,比如可以一直重定向到一個固定頁面。

3. 從2可以看到,其實最終登錄成功要回到哪個頁面,已經在你點擊"login using XXX"這個按鈕時就已經決定了,應該是你在點這個按鈕之前訪問的最後一個受保護的頁面。那爲什麼官方文檔能回到"/主頁",我卻只能回到"/user"這個頁面呢?而且從流程來看,/user這個API是都要調用的,所以/user纔是本來應該的landing page,氣氛上我的結果反而是對的。。。
繼續跟到源碼看官方文檔的那個例子HttpSessionRequestCache.saveRequest()這個方法爲什麼沒把/user的訪問記錄給存下來,發現在做方法的第一行
requestMatcher.matches(request)

時候,代理到了MediaTypeRequestMatcher這個類,原因也沒往細看,主要的區別在於官方用Angular的話在request中添加了Accept的header,而我在用Fetch時候是沒這個Header的。

於是加上Accept:application/json,問題解決。

這種坑真是防不勝防。儘管現在Spring Boot讓一切都看起來簡單了,遇到坑的時候就能體會到這種便利是有代價的。。。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章