国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

登錄認證方式匯總,例如ThreadLocal+攔截器+Redis、JWT

這篇具有很好參考價值的文章主要介紹了登錄認證方式匯總,例如ThreadLocal+攔截器+Redis、JWT。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

登錄方式匯總

先講講傳統(tǒng)的登錄方式

1.Cookie方案

用cookie作為媒介存放用戶憑證。

用戶登錄系統(tǒng)之后,會返回一個加密的cookie,當用戶訪問子應用的時候會帶上這個cookie,授權以解密cookie并進行校驗,校驗通過后即可登錄當前用戶。

缺點:

Cookie不安全,Cookie是存到客戶端的,攻擊者可以偽造Cookie偽造成特定用戶。

2.傳統(tǒng)Session方案

最經典的一種

因為HTTP協(xié)議是一種無狀態(tài)的協(xié)議,這就意味著,某個用戶登錄之后,下一次他再請求時,用戶還得登錄,因為客戶端和服務器是多對一的關系,所以我們不知道那些用戶登錄了,哪些沒登錄。

傳統(tǒng)解決方式:

1. 用戶第一次發(fā)送登錄請求時,用Session存下來用戶的信息,將SessionID用Cookie傳給客戶端。

2. 之后這個瀏覽器每次訪問服務器的時候,看它的Cookie里面有沒有SessionID,用SessionID找到對應的Session,找到了那就說明登錄了,沒找到就是沒登錄。

登錄認證方式匯總,例如ThreadLocal+攔截器+Redis、JWT,java,前端,javascript

簡單示例

SpringBoot項目中寫一個簡單的接口測試一下:

?登錄認證方式匯總,例如ThreadLocal+攔截器+Redis、JWT,java,前端,javascript

訪問接口

登錄認證方式匯總,例如ThreadLocal+攔截器+Redis、JWT,java,前端,javascript

可以在瀏覽器的Cookie中看到有JSESSIONID,就是SessionID

登錄認證方式匯總,例如ThreadLocal+攔截器+Redis、JWT,java,前端,javascript

缺點

  1. 用戶多了之后,Session全部存到服務器中,服務器開銷大。
  2. 分布式的應用中,有多臺服務器,那么Session是存在單個服務器上的,不共享Session,如果用戶在服務器1上登錄之后,下次的請求跳轉到服務器2上了,就需要再次登錄。

3.分布式Session方案

為了解決分布式系統(tǒng)中,多服務器是不共享session,傳統(tǒng)的單機session不適用于分布式系統(tǒng)中,所以這里使用分布式session。

實現分布式session有四種方案:

  1. 數據庫統(tǒng)一存儲
  2. session復制
  3. 客戶端存儲
  4. HASH一致性

具體請看:分布式session解決方案_半格咖啡的博客-CSDN博客

流程:

(1) 用戶第一次登錄時,將會話信息(用戶Id和用戶信息),比如以用戶Id為Key,寫入分布式Session;

(2) 用戶再次登錄時,獲取分布式Session,是否有會話信息,如果沒有則調到登錄頁;

(3) 一般采用Cache中間件實現,建議使用Redis,因此它有持久化功能,方便分布式Session宕機后,可以從持久化存儲中加載會話信息;

(4) 存入會話時,可以設置會話保持的時間,比如15分鐘,超過后自動超時;

缺點

(1)服務器壓力增大:通常session是存儲在內存中的,每個用戶通過認證之后都會將session數據保存在服務器的內存中,而當用戶量增大時,服務器的壓力增大。(可以將數據保存在磁盤中)

(2)擴展性不強:如果將來搭建了多個服務器,雖然每個服務器都執(zhí)行的是同樣的業(yè)務邏輯,但是session數據是保存在內存中的(不是共享的),用戶第一次訪問的是服務器1,當用戶再次請求時可能訪問的是另外一臺服務器2,服務器2獲取不到session信息,就判定用戶沒有登陸過。(可以使用分布式session將session在各個集群中保持一致)

(3)CSRF跨站偽造請求攻擊:session是基于cookie進行用戶識別的, cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊。

ThreadLocal + 攔截器 + Redis 實現登錄鑒權

就是上面所說的 統(tǒng)一在數據庫存儲的方法。

最終實現的效果

這種方式實現了:允許在分布式環(huán)境中實現線程隔離的單點登錄,確保用戶在不同的請求之間共享登錄狀態(tài),并使用Redis作為分布式會話存儲來保持會話一致性。

其實就是解決了兩個問題

  1. 分布式環(huán)境中Session不共享的問題。
  2. 多線程環(huán)境下并發(fā)導致不安全的問題。

解釋

在分布式的環(huán)境下,因為Session是存到服務器上面的,使用session會出現Session不共享數據的問題。那么可以將共享數據存入數據庫中,然后應用服務器就可以去數據庫獲取共享數據。

對于每一次請求,可以在一開始從數據庫里取到數據,然后將其臨時存放在本地的內存里。

考慮到線程安全的問題,所以使用threadlocal進行線程隔離,這樣在本次請求的過程中,就可以隨時獲取到這份共享數據了。

所以,session的替代方案是數據庫,ThreadLocal在這里起輔助的作用。

數據庫不建議用mysql,訪問慢,用Redis的話訪問快。

具體實現流程:

  1. 在登錄業(yè)務代碼中,當用戶登錄成功時,生成一個登錄憑證存儲到redis中,將憑證中的字符串保存在cookie中返回給客戶端。
  2. 以后每次的請求,使用一個攔截器攔截請求,從cookie中獲取憑證字符串。
  3. 將字符串與redis中的憑證進行匹配,獲取用戶信息,將用戶信息存儲到ThreadLocal中,在本次請求中持有用戶信息,即可在后續(xù)操作中使用到用戶信息。

登錄憑證類:

//登錄憑證表
@Data
@ApiModel("登錄憑證類")
public class LoginTicket {

    private int id;
    private int userId;
    //登錄憑證字符串
    private String ticket;
    private int status;
    private Date expired;
}

攔截器

  1. 攔截每一次請求,從request中獲取cookies。
  2. 從cookies里面找到 憑證字符串與redis中的憑證進行匹配,獲取用戶信息。
  3. 將用戶信息存儲到ThreadLocal中,在本次請求中持有用戶信息,即可在后續(xù)操作中使用到用戶信息。

SpringMVC攔截器使用介紹:

1.創(chuàng)建攔截器類

創(chuàng)建一個DemoInterceptor類實現HandlerInterceptor接口。

重寫preHandle(),postHandle(),afterCompletion() 三個方法,如下代碼,我們就創(chuàng)建了一個Spring的攔截器。

  • preHandle():在controller執(zhí)行請求之前執(zhí)行
  • postHandle():在controller執(zhí)行請求之后執(zhí)行,在模板引擎(例如Thymeleaf)之前執(zhí)行
  • afterCompletion() :在模板引擎之后執(zhí)行

2.編寫攔截器配置類

選擇要攔截哪些請求,放行那些資源

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new DemoInterceptor())
                //放行靜態(tài)資源
                .excludePathPatterns("/**/*.css","/**/*.js","/**/*.png","/**/*.jpg","/**/*.jpeg")
                //攔截 注冊 登錄請求
                .addPathPatterns("/register","/login");
    }
}
@Component
public class LoginTicketInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    @Autowired
    private HostHolder hostHolder;

    // 保存登錄信息
    // 調用時間:Controller方法處理之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //從cookie中獲取憑證
        String ticket = CookieUtil.getValue(request, "ticket");

        if (ticket != null){
            //查詢憑證
            LoginTicket loginTicket = userService.findLoginTicket(ticket);
            //檢查憑證是否有效
            if (loginTicket != null && loginTicket.getStatus() == 0 && loginTicket.getExpired().after(new Date())){
                //根據憑證查詢用戶
                User user = userService.findByUserId(loginTicket.getUserId());
                //在本次請求中持有用戶
                hostHolder.setUser(user);
                //構建用戶認證的結果,并存入SecurityContext,以便于Security進行授權
                Authentication authentication = new UsernamePasswordAuthenticationToken(
                        user, user.getPassword(), userService.getAuthorities(user.getId()));
                SecurityContextHolder.setContext(new SecurityContextImpl(authentication));
            }
        }

        return true;
    }

    // 調用時間:Controller方法處理完之后
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //得到當前線程持有的user
        User user = hostHolder.getUser();
        if (user != null && modelAndView != null){
            modelAndView.addObject("loginUser", user);
        }
    }

    // 調用時間:DispatcherServlet進行視圖的渲染之后
    // 請求結束,把保存的用戶信息清除掉
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        hostHolder.clear();
        SecurityContextHolder.clearContext();
    }
}

ThreadLocal

他是什么?

  • 可以理解成它是一個特殊的map,它的key就是線程本身,value就是你想存儲的數據。
  • ThreadLocal本質是以線程為key存儲元素
  • ThreadLocal可以把用戶信息保存在線程中,用戶的每一次請求,就是一個線程,保存了用戶信息,方便我們在后續(xù)操作獲取用戶登錄信息。
  • 當請求結束,也就是用戶點擊了退出登錄之后,我們會把保存的用戶信息清除掉,防止內存泄漏。

為什么用這個ThreadLocal?

????????解決并發(fā)帶來的問題,有助于確保每個用戶的登錄狀態(tài)在不同的線程中得到正確維護和隔離,防止了混淆、安全問題、并發(fā)問題和會話管理問題,從而提高了系統(tǒng)的可靠性和安全性。

????????為了防止多進程對用戶信息修改造成的數據不一致,因此需要保證每個請求(線程)訪問自己的資源(用戶信息)。隔離起來,就不會發(fā)送資源錯誤的問題了。

????????所以在后續(xù)請求中,這個線程一直是存活的,ThreadLocal里面的數據也是一直在的。

????????當請求處理完,服務器向瀏覽器做出響應之后,這個線程就被銷毀了,我們會把保存的用戶信息清除掉,防止內存泄漏。

/**
 *持有用戶信息,用于代替session對象
 */
@Component
public class HostHolder {

    //ThreadLocal本質是以線程為key存儲元素
    private ThreadLocal<User> users = new ThreadLocal<>();

    public void setUser(User user){
        users.set(user);
    }

    public User getUser(){
        return users.get();
    }

    public void clear(){
        users.remove();
    }
}

還有一種常用的:JWT認證

????????登錄功能的實現可以有多種方式,具體取決于開發(fā)人員的需求和技術選擇。有傳統(tǒng)的Session會話機制的,也有JWT的。

????????JSON Web Token 是個令牌,就是通過Json形式作為web應用中的令牌,用于在各方之間安全的將信息作為JSON對象傳輸。

????????JSON Web Token是在各方之間安全地傳輸信息的好方法。

????????因為可以對JWT進行簽名(例如,使用公鑰/私鑰對),所以您可以確保發(fā)件人是他們所說的人。此外,由于簽名是使用標頭和有效負載計算的,因此您還可以驗證內容是否遭到篡改。

JWT是存儲在客戶端的。

流程

登錄認證方式匯總,例如ThreadLocal+攔截器+Redis、JWT,java,前端,javascript

  1. 首先,前端通過Web表單將自己的用戶名和密碼發(fā)送到后端的接口。這一過程一般是一個HTTP POST請求。建議的方式是通過SSL加密的傳輸(https協(xié)議),從而避免敏感信息被嗅探。
  2. 后端核對用戶名和密碼成功后,將用戶的id等其他信息作為JWT Payload(負載),將其與頭部分別進行Base64編碼拼接后簽名
  3. 形成一個JWT(Token)。形成的JWT就是一個形同111.zzz.xxx的字符串。token head.payload.singurater
  4. 后端將JWT字符串作為登錄成功的返回結果返回給前端。前端可以將返回的結果保存在localStorage或sessionStorage上,退出登錄時前端刪除保存的JWT即可。
  5. 前端在每次請求時將JWT放入HTTP Header中的Authorization位。(解決XSS和XSRF問題)HEADEF。
  6. 后端檢查是否存在,如存在驗證JWT的有效性。例如,檢查簽名是否正確;檢查Token是否過期;檢查Token的接收方是否是自己(可選)。
  7. 驗證通過后后端使用JWT中包含的用戶信息進行其他邏輯操作,返回相應結果。

優(yōu)勢

  1. 傳輸速度快:可以通過URL,POST參數或者在HTTP header發(fā)送,因為數據量小,傳輸速度快。
  2. 自包含:負載中包含了所有用戶所需要的信息,避免了多次查詢數據庫。
  3. 跨語言:因為Token是以JSON加密的形式保存在客戶端的,所以JWT是跨語言的,原則上任何web形式都支持。
  4. 支持分布式:因為是存儲到客戶端的,所以不需要在服務端保存會話信息。

?

結構

token string ====> header.payload.singnature token

JWT令牌組成

  • 1.標頭(Header)
  • 2.有效負載(Payload)
  • 3.簽名(Signature)
  • 因此,JWT通常如下所示:xxxxx.yyyyy.zzzzz Header.Payload.Signature

?

1.Header(標頭)

  • 標頭通常由兩部分組成:令牌的類型(即JWT)和所使用的簽名算法,例如HMAC SHA256或RSA。它會使用 Base64 編碼組成 JWT 結構的第一部分。
  • 注意:Base64是一種編碼,也就是說,它是可以被翻譯回原來的樣子來的。它并不是一種加密過程。
{
  "alg": "HS256",
  "typ": "JWT"
}

2.Payload(有效負載)

  • 令牌的第二部分是有效負載,其中包含聲明。聲明是有關實體(通常是用戶)和其他數據的聲明。
  • 同樣的,它會使用Base64 編碼組成 JWT 結構的第二部分
  • 官方不建議放用戶的敏感信息,放些用戶ID、用戶名什么的沒事,不要放密碼。不安全。
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

3.Signature(簽名)

前面兩部分都是使用 Base64 進行編碼的,即前端可以解開知道里面的信息。

Signature 需要使用編碼后的 header 和 payload以及我們提供的一個密鑰

然后使用 header 中指定的簽名算法(HS256)進行簽名。

也就是:3.Signature = 編碼后的1.Header + 編碼后的2.Payload + 密鑰

簽名的作用是保證 JWT 沒有被篡改過

例如

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret);

?

最后一步簽名的過程,實際上是對頭部以及負載內容進行簽名,防止內容被竄改。

如果有人對頭部以及負載的內容解碼之后進行修改,再進行編碼,最后加上之前的簽名組合形成新的JWT的話,那么服務器端會判斷出新的頭部和負載形成的簽名和JWT附帶上的簽名是不一樣的。

如果要對新的頭部和負載進行簽名,在不知道服務器加密時用的密鑰的話,得出來的簽名也是不一樣的。

?

關于密鑰

通常,密鑰存儲在服務器的配置文件或環(huán)境變量中,以確保只有授權的人員可以訪問它。

密鑰的安全性非常重要,因為如果密鑰泄漏,攻擊者可能會偽造有效的JWT令牌來訪問受保護的資源。

不同的請求,服務器的密鑰通常是相同的。

密鑰管理的方式:文章來源地址http://www.zghlxwxcb.cn/news/detail-733216.html

  1. 儲在安全的配置文件或環(huán)境變量中:密鑰應該存儲在服務器上的安全位置,而不是硬編碼在代碼中,以避免泄漏。
  2. 定期輪換密鑰:定期更改密鑰以減小泄漏的風險。如果密鑰不再安全,及時進行輪換。
  3. 限制訪問:確保只有授權的人員可以訪問密鑰存儲。使用訪問控制和權限管理來限制對密鑰的訪問。

到了這里,關于登錄認證方式匯總,例如ThreadLocal+攔截器+Redis、JWT的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • SpingMVC攔截器-用戶登錄權限控制分析

    SpingMVC攔截器-用戶登錄權限控制分析

    1.1 這個后臺工程,沒有進行相關操作也能夠進行登錄: 4.1 5.1 ?選擇test那個文件: 17.1.var可以獲得session對象: 17.2 獲取誰啊!獲取user,返回的是user對象 ?17.3 強轉之后做判斷: ?17.4 如果判斷沒有登錄,這里跳轉,這里我要設置重定向命令: ? 17.5 重定向 17.6 內部requestCon

    2024年02月11日
    瀏覽(20)
  • 登錄頁面jwt密鑰,過濾器,攔截器,異常處理

    需求: 用戶未登錄時,訪問其他也沒面,操作添加、刪除等操作時,強行跳轉至登錄頁面。 實現方法: 1.使用Cookie,登錄后后端添加一個cookie,每次頁面判斷是否有cookie, 2。使用session,原理同上,只不過session是存儲在服務器里的,cookie是在瀏覽器里。 3。使用jwt令牌,登

    2023年04月25日
    瀏覽(26)
  • Spring MVC攔截器Interceptor使用(判斷用戶登錄)

    Spring MVC攔截器Interceptor使用(判斷用戶登錄)

    Spring MVC中的攔截器(Interceptor)類似于Servlet中的過濾器(Filter),它主要用于攔截用戶請求并作相應的處理。例如通過攔截器可以進行權限驗證、記錄請求信息的日志、判斷用戶是否登錄等。 攔截器可以在進入處理器之前做一些操作,或者在處理器完成后進行操作,甚至是

    2024年02月09日
    瀏覽(33)
  • 登錄用戶信息獲取 網關+攔截器+feign請求添加請求頭

    登錄用戶信息獲取 網關+攔截器+feign請求添加請求頭

    給所有請求添加用戶身份 網關已經給所有請求添加了用戶身份,也就是authorization頭信息。 ? 創(chuàng)建ThreadLocal工具類 : 創(chuàng)建攔截器:? 將攔截器注冊到SpringMvc,讓它生效: ?將以上代碼(攔截器,config,utils) 放到哪個微服務中,哪個微服務/**路徑就會有攔截功能 沒有用戶信息的請求將會

    2024年02月09日
    瀏覽(19)
  • Vue3 axios響應攔截器處理接口返回401未登錄跳轉登錄頁

    問題: 在 asiox 使用 useRouter 實例化創(chuàng)建 router 路由對象,在 response 響應攔截器里為 undefined 訪問不到 使用 window.location.href = \\\'/login\\\' 跳轉登錄頁, 本地可以正常跳轉,測試環(huán)境頁面會顯示 not found 404, 測試環(huán)境訪問地址大概是這樣 ip:8080/pm/#/login , 本地沒有 /pm 解決方案: 在 mai

    2024年01月21日
    瀏覽(22)
  • 以配置的方式開關axios攔截器功能

    以配置的方式開關axios攔截器功能

    前景提要: ts 簡易封裝 axios,統(tǒng)一 API axios 很多額外功能都是基于攔截器實現。有些功能想要全局使用,因此將攔截器注冊在全局。比如重復請求過濾。但也有一小部分請求不希望進行過濾,比如并發(fā)上傳文件。 因此希望可以在具體的請求方法上,通過配置 config 從而決定針

    2024年02月06日
    瀏覽(24)
  • anxios封裝攔截器的兩種方式

    使用方法 講解:函數式通過調用方法創(chuàng)建axios實例,通過參數傳入基礎url,超時時間等定義參數。 使用時比較接近axios寫法。 使用方法 類方法: 通過創(chuàng)建一個類,傳入baseUrl,超時時間等自定義參數。使用時候調用類的方法實現創(chuàng)建axios實例。 兩種方法寫法不同,功能相同。

    2024年01月19日
    瀏覽(20)
  • 【Java Web】用攔截器的方式獲取用戶信息

    流程:從cookie中獲取憑證,根據憑證查詢用戶,并在本次請求中持有用戶,在視圖模板上顯示登錄用戶的信息。 1. 定義攔截器 2. 配置攔截器

    2024年02月10日
    瀏覽(22)
  • 【Spring實戰(zhàn)項目】SpringBoot3整合WebSocket+攔截器實現登錄驗證!從原理到實戰(zhàn)

    【Spring實戰(zhàn)項目】SpringBoot3整合WebSocket+攔截器實現登錄驗證!從原理到實戰(zhàn)

    ???? 歡迎光臨,終于等到你啦 ???? ??我是 蘇澤 ,一位對技術充滿熱情的探索者和分享者。???? ??持續(xù)更新的專欄 《Spring 狂野之旅:從入門到入魔》 ?? 本專欄帶你從Spring入門到入魔 ? 這是蘇澤的個人主頁可以看到我其他的內容哦???? 努力的蘇澤 http://suzee.blog.

    2024年04月17日
    瀏覽(21)
  • 【Spring Boot】攔截器與統(tǒng)一功能處理:統(tǒng)一登錄驗證、統(tǒng)一異常處理與統(tǒng)一數據返回格式

    【Spring Boot】攔截器與統(tǒng)一功能處理:統(tǒng)一登錄驗證、統(tǒng)一異常處理與統(tǒng)一數據返回格式

    ?Spring AOP是一個基于面向切面編程的框架,用于將橫切性關注點(如日志記錄、事務管理)與業(yè)務邏輯分離,通過代理對象將這些關注點織入到目標對象的方法執(zhí)行前后、拋出異?;蚍祷亟Y果時等特定位置執(zhí)行,從而提高程序的可復用性、可維護性和靈活性。但使用原生Sp

    2024年02月16日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包