前后端獨立開發,動靜分開部署


好處:

1、讓前后端的開發人員可以更方便的開發和調試,各自專注於處理自己領域的問題;前端開發人員不需要知道后台使用什么技術實現,前后台通信都是基於Rest接口,像是兩個獨立的系統;

2、前端程序都是屬於靜態資源文件,單獨部署,有利於提高訪問性能;從Nginx訪問靜態資源比從Tomcat訪問要更快速;

3、在針對靜態資源文件做CDN優化時,獨立部署一台靜態資源服務器即可,CDN回源不會對應用程序服務器造成影響。

 

解決安全驗證問題

后端是基於Shiro的安全驗證框架

前端通過AJAX訪問后端Rest接口時,如果后端進行安全驗證時,在沒有驗證通過的情況下,給返回:

{
    error : 'NOT_AUTHENTICATED',
    loginUrl : '{url}'
}

前端要有一個針對AJAX請求的全局處理,來檢測該情況。

axios.interceptors.response.use(function (response) {
  if (response.data.error === 'NOT_AUTHENTICATED') {
    redirect(response.data.loginUrl)
    return Promise.reject(response.data.error)
  }
  return response
}, function (error) {
  return Promise.reject(error)
})

重定向到登錄頁面去驗證,需要傳一個backUrl參數,以便於完成登錄驗證后能跳轉回原來的頁面。

如何來處理這個backUrl呢?有兩種方案:

1、前端在發出AJAX請求時,將當前頁面地址(包括路由地址)發送給服務端,由服務端來完成整個loginUrl的裝配工作。

axios.interceptors.request.use(function (config) {
  config.headers.hash = window.location.hash
  return config
}, function (error) {
  return Promise.reject(error)
})

服務端要獲取當前客戶端頁面的完整地址(包括路由地址)就是通過下面的代碼:

            // 獲取發送請求的來源網頁地址
            String sourceUrl = request.getHeader("referer");
            if (StringUtils.isNotEmpty(sourceUrl)) {
                sourceUrl += request.getHeader("hash");
                sourceUrl = URLEncoder.encode(sourceUrl, "utf-8");
            }

這里是在request的head部分增加了個一項hash,但是這個自定義的head項目在跨域訪問時又不被允許。

在跨域訪問的情況下,默認客戶端會發送兩次請求,第一次是探查,Method=OPTION,此時服務端要設置所允許的head項:

response.setHeader("Access-Control-Allow-Headers", "accept,content-type,hash");

2、另一種方式就是服務端下發loginUrl,里面帶有一個占位符,比如“${hash}”,到達客戶端后,由客戶端去替換成當前頁面的完整地址。

這樣就不需要自定義request的head項了。

 

當跳轉到一個loginUrl進行登錄驗證后,如果驗證通過了建立了Session,這個Session如何跟靜態資源網站共享呢?

為了在應用程序和前端靜態頁面之間共享Session,需要把Shiro的SessionCookie保存在根域名之下(動靜兩個應用必須是相同的根域名)。

    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <constructor-arg value="sid"/>
        <property name="httpOnly" value="false"/>
        <property name="maxAge" value="-1"/>
        <property name="domain" value=".6655.la"/>
    </bean>

當設置到這一步時,又會發現跨域情況下,向服務端發送請求,Cookie是不會攜帶的。

必須在第一次發送OPTION探查時,要明確告訴客戶端允許攜帶Cookie

response.setHeader("Access-Control-Allow-Credentials", "true");

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM