最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Token登陸驗證機制的原理及實現(xiàn)

 更新時間:2021年12月02日 14:41:31   作者:程序員自由之路  
這篇文章介紹了Token登陸驗證機制的原理及實現(xiàn),對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

session簡介

做過Web開發(fā)的程序員應該對Session都比較熟悉,Session是一塊保存在服務器端的內(nèi)存空間,一般用于保存用戶的會話信息。

用戶通過用戶名和密碼登陸成功之后,服務器端程序會在服務器端開辟一塊Session內(nèi)存空間并將用戶的信息存入這塊空間,同時服務器會在cookie中寫入一個Session_id的值,這個值用于標識這個內(nèi)存空間。

下次用戶再來訪問的話會帶著這個cookie中的session_id,服務器拿著這個id去尋找對應的session,如果session中已經(jīng)有了這個用戶的登陸信息,則說明用戶已經(jīng)登陸過了。

使用Session保持會話信息使用起來非常簡單,技術(shù)也非常成熟。但是也存在下面的幾個問題:

  • 服務器壓力大:通常Session是存儲在內(nèi)存中的,每個用戶通過認證之后都會將session數(shù)據(jù)保存在服務器的內(nèi)存中,而當用戶量增大時,服務器的壓力增大。
  • Session共享:現(xiàn)在很多應用都是分布式集群,需要我們做額外的操作進行Session共享;
  • CSRF跨站偽造請求攻擊:Session機制是基于瀏覽器端的cookie的,cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊。

基于token的認證

基于token的認證機制將認證信息返回給客戶端并存儲。下次訪問其他頁面,需要從客戶端傳遞認證信息回服務端。簡單的流程如下:

  • 客戶端使用用戶名跟密碼請求登錄;
  • 服務端收到請求,去驗證用戶名與密碼;
  • 驗證成功后,服務端會簽發(fā)一個 Token,再把這個 Token 發(fā)送給客戶端;
  • 客戶端收到 Token 以后可以把它存儲起來,比如放在 Cookie 里或者 Local Storage 里;
  • 客戶端每次向服務端請求資源的時候需要帶著服務端簽發(fā)的 Token;
  • 服務端收到請求,然后去驗證客戶端請求里面帶著的 Token,如果驗證成功,就向客戶端返回請求的數(shù)據(jù);

基于token的驗證機制,有以下的優(yōu)點:

  • 支持跨域訪問,將token置于請求頭中,而cookie是不支持跨域訪問的;
  • 無狀態(tài)化,服務端無需存儲token,只需要驗證token信息是否正確即可,而session需要在服務端存儲,一般是通過cookie中的sessionID在服務端查找對應的session;
  • 無需綁定到一個特殊的身份驗證方案(傳統(tǒng)的用戶名密碼登陸),只需要生成的token是符合我們預期設定的即可;
  • 更適用于移動端(Android,iOS,小程序等等),像這種原生平臺不支持cookie,比如說微信小程序,每一次請求都是一次會話,當然我們可以每次去手動為他添加cookie,詳情請查看博主另一篇博客;
  • 避免CSRF跨站偽造攻擊,還是因為不依賴cookie;

缺點的話一個就是相比較于傳統(tǒng)的session登陸機制實現(xiàn)起來略微復雜一點,另外一個比較大的缺點是由于服務器不保存 token,因此無法在使用過程中廢止某個 token,或者更改 token 的權(quán)限。也就是說,一旦 token 簽發(fā)了,在到期之前就會始終有效,除非服務器部署額外的邏輯。

退出登陸的話,只要前端清除token信息即可。

基于JWT的token認證實現(xiàn)

JWT(JSON Web Token)就是基于token認證的代表,這邊就用JWT為列來介紹基于token的認證機制。

需要引入JWT的依賴

<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>3.8.2</version>
</dependency>

生成token和驗證token的工具類如下:

public class JWTTokenUtil {
    //設置過期時間
    private static final long EXPIRE_DATE=30*60*100000;
    //token秘鑰
    private static final String TOKEN_SECRET = "ZCfasfhuaUUHufguGuwu2020BQWE";

    public static String token (String username,String password){

        String token = "";
        try {
            //過期時間
            Date date = new Date(System.currentTimeMillis()+EXPIRE_DATE);
            //秘鑰及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            //設置頭部信息
            Map<String,Object> header = new HashMap<>();
            header.put("typ","JWT");
            header.put("alg","HS256");
            //攜帶username,password信息,生成簽名
            token = JWT.create()
                    .withHeader(header)
                    .withClaim("username",username)
                    .withClaim("password",password).withExpiresAt(date)
                    .sign(algorithm);
        }catch (Exception e){
            e.printStackTrace();
            return  null;
        }
        return token;
    }

    public static boolean verify(String token){
        /**
         * @desc   驗證token,通過返回true
         * @params [token]需要校驗的串
         **/
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return  false;
        }
    }
    public static void main(String[] args) {
        String username ="name1";
        String password = "pw1";
        //注意,一般不會把密碼等私密信息放在payload中,這邊只是舉個列子
        String token = token(username,password);
        System.out.println(token);
        boolean b = verify(token);
        System.out.println(b);
    }
}

執(zhí)行結(jié)果如下:

Connected to the target VM, address: '127.0.0.1:11838', transport: 'socket'
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXNzd29yZCI6IjEyMyIsImV4cCI6MTU5NzM5Nzc0OCwidXNlcm5hbWUiOiJ6aGFuZ3NhbiJ9.LI5S_nX-YcqtExI9UtKiP8FPqpQW_ccaws2coLzyOS0
true

關于DecodedJWT這個類,大家可以重點看下,里面包含了解碼后的用戶信息。

JWT的使用說明

客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage。

此后,客戶端每次與服務器通信,都要帶上這個 JWT。你可以把它放在 Cookie 里面自動發(fā)送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization字段里面。

Authorization: Bearer <token>

另一種做法是,跨域的時候,JWT 就放在 POST 請求的數(shù)據(jù)體里面。

JWT 本身包含了認證信息,一旦泄露,任何人都可以獲得該令牌的所有權(quán)限。為了減少盜用,JWT 的有效期應該設置得比較短。對于一些比較重要的權(quán)限,使用時應該再次對用戶進行認證。

為了減少盜用,JWT 不應該使用 HTTP 協(xié)議明碼傳輸,要使用 HTTPS 協(xié)議傳輸。(或者是對JWT在前后端之間進行加密之后在傳輸)

關于JWT的一個問題

上面生成JWT token的過程關鍵點就是密鑰,假如這個密鑰泄露了,那是不是就可以偽造token了。

還有就是生產(chǎn)環(huán)境的密鑰值,開發(fā)的程序員大概率是知道的,怎么防止程序要監(jiān)守自盜,偽造token值呢?希望有經(jīng)驗的大佬指教下。

//token秘鑰
private static final String TOKEN_SECRET = "ZCfasfhuaUUHufguGuwu2020BQWE";

關于上面的問題,@仙湖碼農(nóng) 給出了一個簡單易懂的方案~

jwt 來生成token,還有一個玩法,用戶登錄時,生成token的 SecretKey 是一個隨機數(shù),也就是說每個用戶,每次登錄時jwt SecretKey 是隨機數(shù),并保存到緩存,key是登錄賬戶,(當然了,分布式緩存的話,就用Redis,sqlserver緩存等等),總之,客戶端訪問接口是,header 要帶登錄賬戶,和token,服務端拿到登錄賬號,到緩存去撈相應的SecretKey ,然后再進行token校驗??梢苑纻卧靦oken了(這個方案在一定程度上能防止偽造,但是不能防止token泄露被劫持)。

獲取refresh token的方法#

ASP.NET Core應用JWT進行用戶認證及Token的刷新方案

參考#

Java登錄功能實現(xiàn)token生成與驗證

PHP實現(xiàn)JWT的Token登錄認證

JWT使用詳解

JWT官網(wǎng)

以上所述是小編給大家介紹的Token登陸驗證機制的原理及實現(xiàn),希望對大家有所幫助。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

  • 詳解Java中ByteArray字節(jié)數(shù)組的輸入輸出流的用法

    詳解Java中ByteArray字節(jié)數(shù)組的輸入輸出流的用法

    ByteArrayInputStream和ByteArrayOutputStream分別集成自InputStream和OutputStream這兩個輸入和輸出流,這里我們就來詳解Java中ByteArray字節(jié)數(shù)組的輸入輸出流的用法,需要的朋友可以參考下
    2016-06-06
  • Java項目開發(fā)中實現(xiàn)分頁的三種方式總結(jié)

    Java項目開發(fā)中實現(xiàn)分頁的三種方式總結(jié)

    這篇文章主要給大家介紹了關于Java項目開發(fā)中實現(xiàn)分頁的三種方式,通過這一篇文章可以很快的學會java分頁功能,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • spring boot開發(fā)遇到坑之spring-boot-starter-web配置文件使用教程

    spring boot開發(fā)遇到坑之spring-boot-starter-web配置文件使用教程

    Spring Boot支持容器的自動配置,默認是Tomcat,當然我們也是可以進行修改的。這篇文章給大家介紹了spring boot開發(fā)遇到坑之spring-boot-starter-web配置文件使用教程,需要的朋友參考下吧
    2018-01-01
  • @Valid和@Validated注解校驗以及異常處理方式

    @Valid和@Validated注解校驗以及異常處理方式

    在Javaweb開發(fā)中,防止數(shù)據(jù)庫惡意攻擊是至關重要的,盡管前端校驗可以起到一定的篩選作用,但通過工具如postman直接對后端發(fā)起請求的情況仍然需要后端進行嚴格的數(shù)據(jù)校驗,Java生態(tài)下,@Valid注解配合SpringBoot提供了一個便捷高效的后端數(shù)據(jù)校驗方案
    2024-11-11
  • 最全面的JVM優(yōu)化經(jīng)驗總結(jié)

    最全面的JVM優(yōu)化經(jīng)驗總結(jié)

    這篇文章主要介紹了最全面的JVM優(yōu)化經(jīng)驗總結(jié),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,,需要的朋友可以參考下
    2019-06-06
  • springboot?vue測試列表遞歸查詢子節(jié)點下的接口功能實現(xiàn)

    springboot?vue測試列表遞歸查詢子節(jié)點下的接口功能實現(xiàn)

    這篇文章主要為大家介紹了springboot?vue測試列表遞歸查詢子節(jié)點下的接口功能實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • spring解決循環(huán)依賴的簡單方法

    spring解決循環(huán)依賴的簡單方法

    這篇文章主要給大家介紹了關于spring解決循環(huán)依賴的簡單方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Java框架Struts2實現(xiàn)圖片上傳功能

    Java框架Struts2實現(xiàn)圖片上傳功能

    這篇文章主要為大家詳細介紹了Java框架Struts2實現(xiàn)圖片上傳功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Java編程中的檢查型異常與非檢查型異常分析

    Java編程中的檢查型異常與非檢查型異常分析

    這篇文章主要介紹了Java編程中的未檢查型異常與非檢查型異常,以及異常的處理方式,需要的朋友可以參考下
    2017-09-09
  • Java中system.exit(0) 和 system.exit(1)區(qū)別

    Java中system.exit(0) 和 system.exit(1)區(qū)別

    本文主要介紹了Java中system.exit(0) 和 system.exit(1)區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05

最新評論

勃利县| 兴和县| 光山县| 靖州| 连平县| 舟曲县| 南丰县| 易门县| 岑巩县| 来凤县| 五莲县| 石楼县| 台湾省| 陇西县| 从江县| 凤山县| 贞丰县| 安丘市| 泸水县| 太和县| 正镶白旗| 沛县| 砚山县| 抚松县| 五指山市| 木兰县| 乃东县| 阿巴嘎旗| 紫金县| 乌什县| 临江市| 方城县| 炉霍县| 福海县| 奎屯市| 榆树市| 周宁县| 邹城市| 普格县| 罗江县| 恩施市|