記錄一下在SpringBoot中實現簡單的登陸認證

代碼參考博客: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

  • Cookie是把用戶的數據寫給用戶的瀏覽器。
  • Session技術把用戶的數據寫到用戶獨佔的session中。
  • Session對象由服務器建立,開發人員能夠調用request對象的getSession方法獲得session對象。

 

session的實現原理:框架

  1. 服務器是如何實現一個session爲一個用戶的瀏覽器服務的呢???(千萬要搞清楚,服務器是對每一個用戶的瀏覽器都建立一個session對象,也就是說每一個瀏覽器用戶都有一塊內存來存他們的信息!!!)
  2. 在一個用戶向服務器發出請求後,服務器會看這個瀏覽器所夾帶的cookie有沒有sessionId這一項,若是沒有,則說明這個用戶是第一次訪問這個服務器,而後服務器爲這個瀏覽器用戶建立一個session和一個獨一無二的sessionid,並把這個id以cookie的形式寫回給客戶機。
  3. 後面客戶端訪問服務器,都會帶着這個sessionid去,服務器發現客戶機瀏覽器帶session id過來了,就會使用內存中與之對應的session爲之服務。
  4. 額若是瀏覽器也就是客戶端禁止使用cookie怎麼辦,有兩個技術:url重寫 和 隱藏表單域   其實思路都是 想辦法把這個sessionid傳給服務器,讓服務器找到正確的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; }
相關文章
相關標籤/搜索