代碼參考博客:java
https://blog.csdn.net/weixin_37891479/article/details/79527641web
在作學校的課設的時候,發現了安全的問題,就不懷好意的用戶有可能跳過登陸直接訪問系統的界面和使用裏面的功能,因而想爲系統加個安全驗證。如今經常使用的安全框架我知道的就是Shiro還有SpringSecurity,但此次我不打算用框架,採用攔截器filter和session技術實現了一個基於session的登陸認證。spring
先簡單地說一下原理:瀏覽器
session和cookie介紹:安全
首先要知道,session是什麼。 咱們知道HTTP是個無狀態的協議,在WEB開發中,服務器能夠爲每一個用戶瀏覽器建立一個會話對象(session對象),注意:一個瀏覽器獨佔一個session對象(默認狀況下)。所以,在須要保存用戶數據時,服務器程序能夠把用戶數據寫到用戶瀏覽器獨佔的session中,當用戶使用瀏覽器訪問其它程序時,其它程序能夠從用戶的session中取出該用戶的數據,爲用戶服務。 服務器
而cookie,就是把用戶的數據寫在瀏覽器,session是放在服務器的內存中的。 session和cookie都是爲了跟蹤與用戶的會話而誕生的技術cookie
而後cookie和session的簡單區別:session
session的實現原理:框架
實現思路:url
登陸成功的時候,在該瀏覽器用戶所對應的session中,新建一個key爲「hasLoginedUsersMap」,值爲一個Map<String, Object> hasLoginedUsersMap的鍵值對,顧名思義,就是一個記錄了該客戶端所登錄過的用戶信息的Map。(爲何不直接記錄一個"user",User的鍵值對,由於考慮到一個瀏覽器可能用多個用戶去登陸……)而後這個Map裏面,每個鍵值對就是("userId",User),也就是鍵爲用戶id,而後值爲這個User對象。 因此登陸成功後,就先看session裏面有沒有這個Map,若沒有則創建一個並在這個Map裏面添加這個userid和這個user;若是有這個Map就在這個Map中添加這個用戶的userId和User信息。
每一個用戶請求過來,先被Filter攔截下來,通過Filter處理後纔到SpringMVC的servlet。在Filter中,看這個瀏覽器用戶的session,看有沒hasLoginedUsersMap這個Map,若是有,就說明該用戶登陸過了,能夠繼續訪問,若是沒有這個Map,就重定向到別的界面,就不讓他訪問原來的資源。(個人主頁的請求中帶有用戶的userId,若是是主頁請求,就會去Map中看有沒有這個UserId的信息,若是有就登陸過,沒有的話就不讓他訪問。)
下面貼下代碼,登陸和註銷還有filter中的攔截代碼就不上了,主要看看Filter的註冊:
查到在Springboot中通常有兩種註冊這個FIlter的方法:
1.註解註冊法:
在過濾器上添加WebFilter註解
在啓動類添加ServletComponentScan註解:
@WebFilter(filterName = "sessionFilter",urlPatterns = {"/*"}) public class SessionFilter implements Filter {
@SpringBootApplication @ServletComponentScan public class FileUploadApplication { public static void main(String[] args) { SpringApplication.run(FileUploadApplication.class, args); } }
2.javaConfig註冊:
package com.stuPayment.config; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.stuPayment.util.LoginFilter; @Configuration public class FilterConfig { @Bean public FilterRegistrationBean loginSessionFilter() {//這個類應該是Spring給咱們拿來初測filter的 FilterRegistrationBean registration = new FilterRegistrationBean();//新建過濾器的註冊類 registration.setFilter(new LoginFilter());//添加咱們寫好的filter registration.addUrlPatterns("/*");//設置filter的過濾的url模式 return registration;//返回這個就是Spring會幫你注入的那個對象 } }
這裏提一下:
當有多個過濾器須要按順序執行時怎麼辦?
使用註解的配置方法不能配置順序,可是能夠經過過濾器名字的字典順序實現順序過濾(好比AFilter就會在BFilter前執行),顯然這種方法看起來不怎麼正經。
可是咱們可使用第二種配置方法.
經過給註冊類設置order,order越小,執行優先級越高
@Bean public FilterRegistrationBean someFilterRegistration1() { //新建過濾器註冊類 FilterRegistrationBean registration = new FilterRegistrationBean(); // 添加咱們寫好的過濾器 registration.setFilter( new SessionFilter()); // 設置過濾器的URL模式 registration.addUrlPatterns("/*"); //設置過濾器順序 registration.setOrder(1); return registration; }