2022-04-19_spring boot 配置sa-token

spring boot 配置sa-token

前言

  • sa-token一個國產(chǎn)的茂嗓,權(quán)限認證框架。
  • 功能上類似Apache Shiro科阎、Spring Security等述吸。但是更加強大、容易上手
  • 主要解決: 登錄認證锣笨、權(quán)限認證蝌矛、Session會話 等一系列權(quán)限相關(guān)問題。大部分api調(diào)用都是一行代碼就能解決
  • sa-token功能很強大错英。以下簡單記錄登錄認證入撒、權(quán)限認證、路由攔截鑒權(quán)等功能
  • sa-token中椭岩,登錄授權(quán)就是如此的簡單茅逮,不需要什么全局過濾器璃赡,不需要各種亂七八糟的配置!只需要一行簡單的API調(diào)用献雅,即可完成會話的登錄授權(quán)碉考!
  • 只要完成登錄認證、權(quán)限認證挺身、路由攔截鑒權(quán)就可以簡單的為項目增加一個鑒權(quán)系統(tǒng)侯谁。
  • 如果只需要登錄認證,權(quán)限認證都不需要章钾,就更簡單了墙贱。。寫一個路由攔截配置文件贱傀、用戶登錄調(diào)用login方法就搞定一切了惨撇。

1.spring boot 引入sa-token

<!-- Sa-Token 權(quán)限認證, 在線文檔:http://sa-token.dev33.cn/ -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.29.0</version>
</dependency>

2.配置

  • application.yml文件增加如下配置項目,當(dāng)然也可以不增加:

  • # Sa-Token配置
    sa-token: 
        # token名稱 (同時也是cookie名稱)
        token-name: satoken
        # token有效期窍箍,單位s 默認30天, -1代表永不過期 
        timeout: 2592000
        # token臨時有效期 (指定時間內(nèi)無操作就視為token過期) 單位: 秒
        activity-timeout: -1
        # 是否允許同一賬號并發(fā)登錄 (為true時允許一起登錄, 為false時新登錄擠掉舊登錄) 
        is-concurrent: true
        # 在多人登錄同一賬號時串纺,是否共用一個token (為true時所有登錄共用一個token, 為false時每次登錄新建一個token) 
        is-share: false
        # token風(fēng)格
        token-style: uuid
        # 是否輸出操作日志 
        is-log: false
    

3.登錄認證

  • 所謂登錄認證,說白了就是限制某些API接口必須登錄后才能訪問椰棘。

  • 如何判斷一個會話是否已經(jīng)登錄纺棺?用戶登錄后,服務(wù)器端調(diào)用login方法邪狞。sa-token會幫我們對會話進行做個標(biāo)記祷蝌。每次需要登錄認證的時候校驗這些標(biāo)記。有標(biāo)記者視為已登錄帆卓,無標(biāo)記者視為未登錄巨朦。

  • 默認,不特殊處理的情況下剑令,sa-token是通過cookie來標(biāo)記的糊啡。如果清掉了cookie,則需要重新登錄吁津。

  • // 標(biāo)記當(dāng)前會話登錄的賬號id 
    // 建議的參數(shù)類型:long | int | String棚蓄, 不可以傳入復(fù)雜類型,如:User碍脏、Admin等等
    StpUtil.login(Object id);     
    
    // 當(dāng)前會話注銷登錄
    StpUtil.logout();
    
    // 獲取當(dāng)前會話是否已經(jīng)登錄梭依,返回true=已登錄,false=未登錄
    StpUtil.isLogin();
    
    // 檢驗當(dāng)前會話是否已經(jīng)登錄, 如果未登錄典尾,則拋出異常:`NotLoginException`
    StpUtil.checkLogin()
    
    // 獲取當(dāng)前會話賬號id, 如果未登錄役拴,則拋出異常:`NotLoginException`
    StpUtil.getLoginId();
    
    // 類似查詢API還有:
    StpUtil.getLoginIdAsString();    // 獲取當(dāng)前會話賬號id, 并轉(zhuǎn)化為`String`類型
    StpUtil.getLoginIdAsInt();       // 獲取當(dāng)前會話賬號id, 并轉(zhuǎn)化為`int`類型
    StpUtil.getLoginIdAsLong();      // 獲取當(dāng)前會話賬號id, 并轉(zhuǎn)化為`long`類型
    
    // ---------- 指定未登錄情形下返回的默認值 ----------
    
    // 獲取當(dāng)前會話賬號id, 如果未登錄,則返回null 
    StpUtil.getLoginIdDefaultNull();
    
    // 獲取當(dāng)前會話賬號id, 如果未登錄钾埂,則返回默認值 (`defaultValue`可以為任意類型)
    StpUtil.getLoginId(T defaultValue);
    
    // 獲取指定token對應(yīng)的賬號id河闰,如果未登錄科平,則返回 null
    StpUtil.getLoginIdByToken(String tokenValue);
    
    // 獲取當(dāng)前`StpLogic`的token名稱
    StpUtil.getTokenName();
    
    // 獲取當(dāng)前會話的token值
    StpUtil.getTokenValue();
    
    // 獲取當(dāng)前會話的token信息參數(shù)
    StpUtil.getTokenInfo();
    
    

4.權(quán)限認證

  • 所謂權(quán)限認證,認證的核心就是一個賬號是否擁有一個權(quán)限碼姜性。有匠抗,就讓你通過。沒有污抬?那么禁止訪問!

  • 再往底了說,就是每個賬號都會擁有一個權(quán)限碼集合绳军,我來校驗這個集合中是否包含指定的權(quán)限碼

  • 例如:當(dāng)前賬號擁有權(quán)限碼集合:["user-add", "user-delete", "user-get"]印机,這時候我來校驗權(quán)限 "user-update",則其結(jié)果就是:驗證失敗门驾,禁止訪問

  • 所以核心問題如下:

4.1 獲取當(dāng)前賬號的權(quán)限碼集合

  • 你需要做的就是新建一個類射赛,實現(xiàn)StpInterface接口

  • 添加@Component保證此類被SpringBoot掃描,完成Sa-Token的自定義權(quán)限驗證擴展

  • 注意方法傳入的loginID奶是。實際項目需要更加loginID實際返回該ID對于的權(quán)限楣责。

  • /**
     * 自定義權(quán)限驗證接口擴展 
     */
    @Component    // 保證此類被SpringBoot掃描,完成Sa-Token的自定義權(quán)限驗證擴展 
    public class StpInterfaceImpl implements StpInterface {
    
        /**
         * 返回一個賬號所擁有的權(quán)限碼集合 
         */
        @Override
        public List<String> getPermissionList(Object loginId, String loginType) {
            // 本list僅做模擬聂沙,實際項目中要根據(jù)具體業(yè)務(wù)邏輯來查詢權(quán)限
            List<String> list = new ArrayList<String>();    
            list.add("101");
            list.add("user-add");
            list.add("user-delete");
            list.add("user-update");
            list.add("user-get");
            list.add("article-get");
            return list;
        }
    
        /**
         * 返回一個賬號所擁有的角色標(biāo)識集合 (權(quán)限與角色可分開校驗)
         */
        @Override
        public List<String> getRoleList(Object loginId, String loginType) {
            // 本list僅做模擬秆麸,實際項目中要根據(jù)具體業(yè)務(wù)邏輯來查詢角色
            List<String> list = new ArrayList<String>();    
            list.add("admin");
            list.add("super-admin");
            return list;
        }
    
    }
    
    

4.2權(quán)限認證

  • 告訴了sa-token用戶所擁有的權(quán)限或角色后。就可以用以下api來鑒權(quán)了

  • // 判斷:當(dāng)前賬號是否含有指定權(quán)限, 返回true或false
    StpUtil.hasPermission("user-update");        
    
    // 校驗:當(dāng)前賬號是否含有指定權(quán)限, 如果驗證未通過及汉,則拋出異常: NotPermissionException 
    StpUtil.checkPermission("user-update");        
    
    // 校驗:當(dāng)前賬號是否含有指定權(quán)限 [指定多個沮趣,必須全部驗證通過]
    StpUtil.checkPermissionAnd("user-update", "user-delete");        
    
    // 校驗:當(dāng)前賬號是否含有指定權(quán)限 [指定多個,只要其一驗證通過即可]
    StpUtil.checkPermissionOr("user-update", "user-delete");        
    
    // 判斷:當(dāng)前賬號是否擁有指定角色, 返回true或false
    StpUtil.hasRole("super-admin");        
    
    // 校驗:當(dāng)前賬號是否含有指定角色標(biāo)識, 如果驗證未通過坷随,則拋出異常: NotRoleException
    StpUtil.checkRole("super-admin");        
    
    // 校驗:當(dāng)前賬號是否含有指定角色標(biāo)識 [指定多個房铭,必須全部驗證通過]
    StpUtil.checkRoleAnd("super-admin", "shop-admin");        
    
    // 校驗:當(dāng)前賬號是否含有指定角色標(biāo)識 [指定多個,只要其一驗證通過即可] 
    StpUtil.checkRoleOr("super-admin", "shop-admin"); 
    

5.路由攔截鑒權(quán)

  • 為什么需要路由攔截鑒權(quán)温眉?

  • 方法1:每個方法手動調(diào)用如上的鑒權(quán)api缸匪。如果沒有權(quán)限就不執(zhí)行。类溢。這個辦法侵入性太高

  • 方法2:注解鑒權(quán)凌蔬。。豌骏。這個辦法同樣不太方便龟梦。。窃躲。需要修改api接口的注解计贰。

  • 方法3:自己動手書寫全局攔截器

  • 方法4:sa-token提供的路由攔截鑒權(quán)。蒂窒。這個是比較方便的躁倒。荞怒。改動比較少。只需要配置相關(guān)配置類秧秉『肿溃基本上所有事情就搞定了。象迎。荧嵌。

  • 增加如下配置類即可。如下代碼注冊了一個登錄認證攔截器砾淌,并且排除了/user/doLogin接口用來開放登錄(除了/user/doLogin以外的所有接口都需要登錄才能訪問)

  • @Configuration
    public class SaTokenConfigure implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 注冊路由攔截器啦撮,自定義認證規(guī)則 
            registry.addInterceptor(new SaRouteInterceptor((req, res, handler)->{
                // 根據(jù)路由劃分模塊,不同模塊不同鑒權(quán) 
                SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
                SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
                SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
                SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
                SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
                SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
            })).addPathPatterns("/**")
                .excludePathPatterns("/user/doLogin"); 
        }
    }
    
    
  • 在校驗函數(shù)內(nèi)不只可以使用 StpUtil.checkPermission("xxx") 進行權(quán)限校驗汪厨,你還可以寫任意代碼

  • 最重要的是日記記錄赃春。。

  • // 登錄認證 -- 攔截所有路由劫乱,并排除/user/doLogin 用于開放登錄 
    SaRouter.match("/**", "/user/doLogin", r -> StpUtil.checkLogin());
    // 角色認證 -- 攔截以 admin 開頭的路由织中,必須具備 admin 角色或者 super-admin 角色才可以通過認證 
    SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));
    // 甚至你可以隨意的寫一個打印語句
    SaRouter.match("/**", r -> System.out.println("----啦啦啦----"));
    // 連綴寫法
    SaRouter.match("/**").check(r -> System.out.println("----啦啦啦----"));
    
  • 除了上述示例的 path 路由匹配,還可以根據(jù)很多其它特征進行匹配衷戈,以下是所有可匹配的特征:

  • // 基礎(chǔ)寫法樣例:匹配一個path狭吼,執(zhí)行一個校驗函數(shù) 
    SaRouter.match("/user/**").check(r -> StpUtil.checkLogin());
    
    // 根據(jù) path 路由匹配   ——— 支持寫多個path,支持寫 restful 風(fēng)格路由 
    SaRouter.match("/user/**", "/goods/**", "/art/get/{id}").check( /* 要執(zhí)行的校驗函數(shù) */ );
    
    // 根據(jù) path 路由排除匹配 
    SaRouter.match("/**").notMatch("*.html", "*.css", "*.js").check( /* 要執(zhí)行的校驗函數(shù) */ );
    
    // 根據(jù)請求類型匹配 
    SaRouter.match(SaHttpMethod.GET).check( /* 要執(zhí)行的校驗函數(shù) */ );
    
    // 根據(jù)一個 boolean 條件進行匹配 
    SaRouter.match( StpUtil.isLogin() ).check( /* 要執(zhí)行的校驗函數(shù) */ );
    
    // 根據(jù)一個返回 boolean 結(jié)果的lambda表達式匹配 
    SaRouter.match( r -> StpUtil.isLogin() ).check( /* 要執(zhí)行的校驗函數(shù) */ );
    
    // 多個條件一起使用 
    SaRouter.match(SaHttpMethod.GET).match("/**").check( /* 要執(zhí)行的校驗函數(shù) */ );
    
    // 可以無限連綴下去 
    SaRouter
        .match(SaHttpMethod.GET)
        .match("/admin/**")
        .match("/user/**") 
        .notMatch("/**/*.js")
        .notMatch("/**/*.css")
        // ....
        .check( /* 只有上述所有條件都匹配成功脱惰,才會執(zhí)行最后的check校驗函數(shù) */ );
    
    

參考文章

1.sa-token官方文檔路由攔截鑒權(quán)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搏嗡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子拉一,更是在濱河造成了極大的恐慌采盒,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔚润,死亡現(xiàn)場離奇詭異磅氨,居然都是意外死亡,警方通過查閱死者的電腦和手機嫡纠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門烦租,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人除盏,你說我怎么就攤上這事叉橱。” “怎么了者蠕?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵窃祝,是天一觀的道長。 經(jīng)常有香客問我踱侣,道長粪小,這世上最難降的妖魔是什么大磺? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮探膊,結(jié)果婚禮上杠愧,老公的妹妹穿的比我還像新娘。我一直安慰自己逞壁,他們只是感情好流济,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腌闯,像睡著了一般袭灯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绑嘹,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音橘茉,去河邊找鬼工腋。 笑死,一個胖子當(dāng)著我的面吹牛畅卓,可吹牛的內(nèi)容都是我干的擅腰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼翁潘,長吁一口氣:“原來是場噩夢啊……” “哼趁冈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拜马,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤渗勘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俩莽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旺坠,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年扮超,在試婚紗的時候發(fā)現(xiàn)自己被綠了取刃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡出刷,死狀恐怖璧疗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情馁龟,我是刑警寧澤崩侠,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站屁柏,受9級特大地震影響啦膜,放射性物質(zhì)發(fā)生泄漏有送。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一僧家、第九天 我趴在偏房一處隱蔽的房頂上張望雀摘。 院中可真熱鬧,春花似錦八拱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爹谭。三九已至,卻和暖如春诺凡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腹泌。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工嘶卧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凉袱,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓专甩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涤躲。 傳聞我的和親對象是個殘疾皇子携添,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容