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

Satoken+Redis實現(xiàn)短信登錄、注冊、鑒權功能

 更新時間:2024年01月03日 10:25:54   作者:阿輝___  
這篇文章主要介紹了Satoken+Redis實現(xiàn)短信登錄、注冊、鑒權功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧

Springboot集成Satoken

添加依賴

注:如果你使用的是 SpringBoot 3.x,只需要將 sa-token-spring-boot-starter 修改為 sa-token-spring-boot3-starter 即可。

<!-- Sa-Token 權限認證,在線文檔:https://sa-token.cc -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.34.0</version>
</dependency>

設置配置文件

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

啟動類

在項目中新建包 com.pj ,在此包內(nèi)新建主類 SaTokenDemoApplication.java,復制以下代碼:

@SpringBootApplication
public class SaTokenDemoApplication {
    public static void main(String[] args) throws JsonProcessingException {
        SpringApplication.run(SaTokenDemoApplication.class, args);
        System.out.println("啟動成功:Sa-Token配置如下:" + SaManager.getConfig());
    }
}

登錄

用戶輸入手機號,調(diào)用登錄接口,根據(jù)手機號查詢是否存在該用戶

@PostMapping("/login")
public Boolean login(@RequestBody String phone) {
  //從數(shù)據(jù)庫查詢該手機號的用戶
  User user = userInfoDao.selectUser(phone);
  //若不存在該用戶返回false,存在返回true
  return user == null ? false : true;
}

確認用戶存在后就可以調(diào)用發(fā)送驗證碼接口,再校驗驗證碼是否正確

/**
 * 發(fā)送驗證碼:
 * 在redis中用hash存儲用戶的相關信息,用PHONE_NUM+手機號作為用戶hash的key,
 * “code”作為用戶信息hash中驗證碼的小key,查詢redis中用戶的驗證碼信息,
 * "num"是驗證次數(shù)的小key
 */
@PostMapping("/sendCaptcha")
public String sendCaptcha(String phone){
    //驗證碼verCode
    String verCode;
    String key = "PHONE_NUM"+phone;
    //如果redis中有緩存的驗證碼
    Object object = redisTemplate.opsForHash().get(key, "code");
    if(null != object){
        throw Error("該用戶驗證碼已發(fā)送,且未過期,請輸入驗證碼登錄或注冊!");
    }else {
        Random r = new Random(System.currentTimeMillis());
        int low = 100000;
        int high = 999999;
        //根據(jù)時間隨機生成驗證碼verCode,將其放入redis中
        int code = (r.nextInt(high - low) + low);
        verCode = String.valueOf(code);
        redisTemplate.opsForHash().put(key,"code",verCode);
        //放入檢驗次數(shù)num=5
        redisTemplate.opsForHash().put(key,"num",5);
        //設置過期時間
        redisTemplate.expire(key,60*5,TimeUnit.SECONDS);
    }
    try {
        //調(diào)用發(fā)送驗證碼的接口發(fā)送驗證碼
        String smsResult= sendMsg(phone, verCode);
    }catch (Throwable throwable){
        redisTemplate.delete(key);
        throw Error("短信發(fā)送失??!");
    }
    return "發(fā)送成功";
}

重點?。?!

/**
 * 校驗驗證碼:
 * 驗證成功就StpUtil.login(user.getId())進行登錄,自動生成token并寫入cookie中
 */
@PostMapping("/checkCaptcha")
public String checkCaptcha(String phone,String verCode){
    if(phone==null||verCode==null||phone==""||verCode==""){
        throw Errorr("請輸入手機及驗證碼!");
    }
    //從redis中獲取該手機號用戶的信息
    String key = "PHONE_NUM"+phone;
    Object object = redisTemplate.opsForHash().get(key, "code");
    if(null == object){
        throw Error("未請求驗證碼或驗證碼已失效,請重新登錄!");
    }
    String code= object.toString();
    if(code.equals(verCode)){
        //驗證碼比對正確,刪除redis中驗證碼記錄
        redisTemplate.delete(key);
        //從數(shù)據(jù)庫查詢出該用戶的信息,并調(diào)用stputil進行登錄
        User user = userService.findUser(phone);
        StpUtil.login(user.getId());
        return "登陸成功";
    }else{
        //驗證碼比對錯誤,校驗次數(shù)減1
        double num = redisTemplate.opsForHash().increment(key,"num",-1);
        //若校驗次數(shù)小于0則驗證碼失效,不小于0則拋出驗證碼錯誤
        if(num < 0 ){
            redisTemplate.delete(key);
            return "未請求驗證碼或驗證碼已失效,請重新登錄!";
        } else {
            return "驗證碼錯誤!";
        }
    }
}

注銷

@PostMapping("/logout")
public Boolean logout() {
    if (!StpUtil.isLogin()) {
    throw Error("未檢測到登錄信息,請先登錄!");
    }
    StpUtil.logout();
    return true;
}

注冊

填入手機號后,若調(diào)用登錄接口根據(jù)手機號查詢數(shù)據(jù)庫發(fā)現(xiàn)不存在該用戶,自動跳轉(zhuǎn)到注冊頁面

@PostMapping("/regist)
public Boolean regist(String userName,String verCode) {
    if(userName==null||verCode==null||userName==""||verCode==""){
        throw Errorr("請輸入用戶名或驗證碼!");
    }
    查詢數(shù)據(jù)庫檢查該用戶名是否已經(jīng)被用;
    調(diào)用上面登錄里的校驗用戶驗證碼的方法;
    用戶名未被占用且驗證碼正確,則向數(shù)據(jù)庫用戶表插入該用戶信息,得到用戶id;
    //調(diào)用stputil進行登錄
    StpUtil.login(userId());
    return true;
}

重寫獲取權限或角色的接口

接口的調(diào)用往往需要權限的校驗,一般的系統(tǒng)會給用戶綁定某種角色,再給此角色分配權限,設置權限碼,具有此角色或者權限碼才放行請求。sa-token實現(xiàn)權限需要進行自定義擴展,下面是獲取一個用戶權限碼集合和角色標識集合的類:

/**
 * 自定義權限驗證接口擴展
 */
@Component    // 保證此類被SpringBoot掃描,完成Sa-Token的自定義權限驗證擴展
public class StpInterfaceImpl implements StpInterface {
    /**
     * 返回一個賬號所擁有的權限碼集合
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        List<String> list = new ArrayList<String>();
        //1.先從redis中根據(jù)loginId取該用戶的權限,有則直接返回
        //2.若是redis中沒有,則從數(shù)據(jù)庫中查詢,再把結(jié)果添加到redis中
        return list;
        // 比如:
        // list.add("101");
        // list.add("user.add");
        // list.add("user.update");
        // list.add("user.get");
        // list.add("user.delete");
        // list.add("art.*");
    }
    /**
     * 返回一個賬號所擁有的角色標識集合 (權限與角色可分開校驗)
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
         List<String> list = new ArrayList<String>();
        //1.先從redis中根據(jù)loginId取該用戶的角色集合,有則直接返回
        //2.若是redis中沒有,則從數(shù)據(jù)庫中查詢,再把結(jié)果添加到redis中
        return list;
        // 比如:
        // list.add("admin");
        // list.add("super-admin");
    }
}

路由攔截實現(xiàn)鑒權

在調(diào)用后臺服務時,我們可以在路由時做一些攔截,例如添加登陸權限攔截、放開一些接口白名單等。(一定要排除 登錄、注冊、發(fā)送驗證碼等接口 的攔截)

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    // 注冊 Sa-Token 的攔截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注冊路由攔截器,自定義認證規(guī)則
        registry.addInterceptor(new SaInterceptor(handler -> {
            //SaRouter.match(參數(shù)一:需要攔截的路由,
                              參數(shù)二:可排除的路由,
                              參數(shù)三:用來檢驗是否通過攔截的方法)
            // 登錄校驗 -- 用是否登錄攔截所有路由,
            // 在最下面的.excludePathPatterns中并排除登錄等接口的攔截
            SaRouter.match("/**", r -> StpUtil.checkLogin());
            // 角色校驗 -- 攔截以 admin 開頭的路由,必須具備 admin 角色或者 super-admin 角色才可以通過認證
            SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));
            // 權限校驗 -- 不同模塊校驗不同權限
            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"));
            // 甚至你可以隨意的寫一個打印語句
            SaRouter.match("/**", r -> System.out.println("----啦啦啦----"));
            // 連綴寫法
            SaRouter.match("/**").check(r -> System.out.println("----啦啦啦----"));
        })).addPathPatterns("/**")
           // 排除登錄、注冊、發(fā)送驗證碼等接口 的攔截
           .excludePathPatterns("/user/login")
           .excludePathPatterns("/user/sendCaptcha")
           .excludePathPatterns("/user/checkCaptcha")
           .excludePathPatterns("/user/regist")
        ;
    }
}

到此這篇關于Satoken+Redis實現(xiàn)短信登錄、注冊、鑒權的文章就介紹到這了,更多相關Redis短信登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Centos7安裝redis的超詳細步驟教程

    Centos7安裝redis的超詳細步驟教程

    Redis是當前比較熱門的NOSQL系統(tǒng)之一,它是一個key-value存儲系統(tǒng),下面這篇文章主要介紹了Centos7安裝redis的超詳細步驟,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • 詳解centos7 yum安裝redis及常用命令

    詳解centos7 yum安裝redis及常用命令

    這篇文章主要介紹了centos7 yum安裝redis及常用命令,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Redis TTL命令實現(xiàn)數(shù)據(jù)生存時間

    Redis TTL命令實現(xiàn)數(shù)據(jù)生存時間

    生存時間可以通過Redis中的不同命令來設置、查看和管理,TTL命令是其中之一,本文主要介紹了Redis TTL命令實現(xiàn)數(shù)據(jù)生存時間,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06
  • redis主從復制的原理及實現(xiàn)

    redis主從復制的原理及實現(xiàn)

    Redis主從復制是一種數(shù)據(jù)同步機制,它通過將一個Redis實例的數(shù)據(jù)復制到其他Redis,本文主要介紹了redis主從復制的原理及實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • redis數(shù)據(jù)一致性的實現(xiàn)示例

    redis數(shù)據(jù)一致性的實現(xiàn)示例

    所謂的redis數(shù)據(jù)一致性即當進行修改或者保存、刪除之后,redis中的數(shù)據(jù)也應該進行相應變化,本文主要介紹了redis數(shù)據(jù)一致性,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 淺談redis整數(shù)集為什么不能降級

    淺談redis整數(shù)集為什么不能降級

    本文主要介紹了redis整數(shù)集為什么不能降級,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • 在Mac OS上安裝Vagrant和Docker的教程

    在Mac OS上安裝Vagrant和Docker的教程

    這篇文章主要介紹了在Mac OS上安裝Vagrant和Docker的教程,并安裝和設置Postgres和Elasticsearch和Redis,需要的朋友可以參考下
    2015-04-04
  • Redis并發(fā)問題解決方案

    Redis并發(fā)問題解決方案

    在當前的互聯(lián)網(wǎng)環(huán)境中,高并發(fā)業(yè)務場景十分常見,本文就來介紹一下Redis并發(fā)問題解決方案,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Redis教程之代理ip池設計方法詳解

    Redis教程之代理ip池設計方法詳解

    這篇文章主要介紹了Redis實現(xiàn)代理ip池的設計方法,文中給出了詳細的介紹與示例代碼,相信對大家的理解和學習具有一定的參考借鑒價值,有需要的朋友們下面來一起看看吧。
    2017-01-01
  • Redis教程(二):String數(shù)據(jù)類型

    Redis教程(二):String數(shù)據(jù)類型

    這篇文章主要介紹了Redis教程(二):String數(shù)據(jù)類型,本文講解了String數(shù)據(jù)類型概述、相關命令列表、命令使用示例三部分內(nèi)容,需要的朋友可以參考下
    2015-04-04

最新評論

革吉县| 青河县| 萨嘎县| 开阳县| 安康市| 江孜县| 安康市| 巧家县| 淮阳县| 临夏县| 临清市| 金秀| 江津市| 南昌市| 西和县| 西乌珠穆沁旗| 宁夏| 江北区| 洛阳市| 杂多县| 江阴市| 汉川市| 安岳县| 美姑县| 伊川县| 闽侯县| 天门市| 马尔康县| 井研县| 南部县| 长岛县| 土默特左旗| 广汉市| 嘉峪关市| 蓬溪县| 慈溪市| 共和县| 夏津县| 罗城| 舒城县| 临夏县|