目錄
1、跨域問題
2、后端代碼問題
3、前端代碼問題
我相信登錄這個功能是很多人做項目時候遇到第一個檻!
**看起來好像很簡單的登錄功能,實際上還是有點坑的,比如明明賬號密碼都填寫正確了,**為什么登錄后請求接口又說我沒登錄?為什么我登錄成功跳轉了頁面卻拿不到用戶信息?
這篇文章,我列舉常見的幾種情況和解決方案,供大家參考。
1、跨域問題
報錯如上所示,所謂的跨域****指的是:比如前端的域名是 aaa.com,訪問后端服務域名 bbb.com,此時的行為就是跨域。
更專業一點的描述就是:在****不同域(域名、協議、端口號任何一個不同)之間進行通信時,就是跨域。
注意哦,是域名、協議、端口號任何一個!協議包括 http 和 https 的區別!
實際上跨域是瀏覽器的限制,它是出于安全考慮阻止這種行為,這種安全策略稱為同源策略(Same-Origin Policy),沒錯它是好心的,但是確實因為它傷害了很多剛入門的同學心。
那跨域問題和登錄有什么關系呢?
實際上我們很多登錄場景都得用到 cookie,比如我們把 session 存在 cookie 里面或者把 token 存 cookie 里,這存的不就是我們的用戶憑證信息嗎?
而 cookie 是跟域名走的!根據同源策略,不同域名之間的 cookie 是不通的,這一舉措是為了確保網站的敏感數據不會被其他域名的網站惡意獲取。
所以不同域之間的 cookie 不互通,導致登錄的用戶憑證信息不互通,導致前端請求后端的時候無法帶上用戶憑證,或者后端回種用戶憑證的時候前端拿不到。
綜上使得大家登錄失效!無法獲取用戶信息!
那怎么解決這個問題呢?
1)保持域名一致
這個應該很好理解,既然瀏覽器限制不同域之間的信息不互通,那么我們在一個域下操作就好了。
可以讓前端和后端接口域名保持一致,用 Nginx 進行端口轉發。
2)后端設置
后端有跨域的配置,指定允許跨域的域名,這樣瀏覽器就知道了這個源是被允許的,大家就可以友好的互通了!
比如我后端的域名是 bbb.com,此時我允許 aaa.com 來調用我,那么就可以這樣配置:
@Configuration
public class CorsConfig {@Beanpublic FilterRegistrationBean<CorsFilter> corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);// 填寫前端域名config.addAllowedOrigin("http://aaa.com");config.addAllowedHeader("*");config.addAllowedMethod("*");source.registerCorsConfiguration("/**", config);FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));bean.setOrder(Ordered.HIGHEST_PRECEDENCE);return bean;}
}
或者只是某個 Controller 上需要配置跨域:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;@RestController
@CrossOrigin(origins = "http://aaa.com")
public class MyController {// 控制器方法
}
或者只是 Controller 上的某個方法需要配置:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MyController {@GetMapping("/data")@CrossOrigin(origins = "http://aaa.com")public String getData() {// 處理方法return "Data";}
}
然后再補充一下常用的這個注解的相關屬性的含義:
origins:允許的來源域,可以是一個字符串數組。
methods:允許的 HTTP 方法,如 GET、POST 等。
allowedHeaders:允許的請求頭。
exposedHeaders:暴露給瀏覽器的響應頭。
allowCredentials:是否允許發送身份驗證信息(如 Cookie)。
maxAge:預檢請求的有效期。
如果項目里用了@CrossOrigin注解還是報錯,可以試試在后端的 @CrossOrigin 注解加 allowCredentials=“true”。
2、后端代碼問題
如果我們確認沒有跨域問題,那么就得看看是不是代碼層面的bug了。
首先我們得懷疑后端的邏輯,確保我們正常的返回了用戶憑證或者一些用戶信息。
比如通過 F12 確認后端登錄接口是否正常返回數據,通過控制臺或者服務器查看日志,看看登錄接口被調用時是否有報錯,有時候可能是因為報錯被 try catch 導致沒有異常信息等等。
3、前端代碼問題
確定沒有跨域問題,且后端接口正常返回用戶信息后,此時我們需要把懷疑的目光轉向前端代碼邏輯!
1)正常登錄后發現獲取不到用戶的信息?
可能是前端的用戶數據取值和后端返回數據結構不匹配。
2)點擊一個頁面,發現登錄態竟然失效了?
可能就是前端在請求時沒有帶上 cookie,需要在 requestConfig.ts 中添加上withCredentials: true。
3)app.ts 里配置的是 localhost,用 127.0.0.1 來訪問就帶不上用戶信息?
因為這樣 cookie 就種不上,改成 127.0.0.1 即可。
**以上就是本次的學習分享,希望對大家有所幫助,****關注我!**不定期分享有用干貨!!!
如果有疑問的可以評論提出來~