国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
1. 基於session 實作簡訊登入
1.1 簡訊登入流程圖
1.2 實作傳送簡訊驗證碼
1.3 實作簡訊驗證碼登入、註冊
3.1 Redis 實作共享session 登入流程圖
前端請求說明:
刷新token 攔截器實作:
首頁 資料庫 Redis Redis的分享session應(yīng)用如何實現(xiàn)簡訊登入

Redis的分享session應(yīng)用如何實現(xiàn)簡訊登入

Jun 03, 2023 pm 03:11 PM
redis session

1. 基於session 實作簡訊登入

1.1 簡訊登入流程圖

Redis的分享session應(yīng)用如何實現(xiàn)簡訊登入

1.2 實作傳送簡訊驗證碼

前端請求說明:


說明
請求方式 POST
#請求路徑 /user/code
#請求參數(shù) phone(電話號碼)
返回值

後端介面實作:

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Override
    public Result sendCode(String phone, HttpSession session) {
        // 1. 校驗手機號
        if(RegexUtils.isPhoneInvalid(phone)){
            // 2. 如果不符合,返回錯誤信息
            return Result.fail("手機號格式錯誤!");
        }
        // 3. 符合,生成驗證碼(設(shè)置生成6位)
        String code = RandomUtil.randomNumbers(6);
        // 4. 保存驗證碼到 session
        session.setAttribute("code", code);
        // 5. 發(fā)送驗證碼(這里并未實現(xiàn),通過日志記錄)
        log.debug("發(fā)送短信驗證碼成功,驗證碼:{}", code);
        // 返回 ok
        return Result.ok();
    }
}

1.3 實作簡訊驗證碼登入、註冊

前端請求說明

##說明請求方式POST請求路徑/ user/login請求參數(shù)phone(電話號碼);code(驗證碼)回傳值無

後端介面實作:

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Override
    public Result login(LoginFormDTO loginForm, HttpSession session) {
        // 1. 校驗手機號
        String phone = loginForm.getPhone();
        if(RegexUtils.isPhoneInvalid(phone)){
            // 不一致,返回錯誤信息
            return Result.fail("手機號格式錯誤!");
        }
        // 2. 校驗驗證碼
        String cacheCode = (String) session.getAttribute("code");
        String code = loginForm.getCode();
        if(cacheCode == null || !cacheCode.equals(cacheCode)){
            // 不一致,返回錯誤信息
            return Result.fail("驗證碼錯誤!");
        }
        // 4. 一致,根據(jù)手機號查詢用戶(這里使用的 mybatis-plus)
        User user = query().eq("phone", phone).one();
        // 5. 判斷用戶是否存在
        if(user == null){
            // 6. 不存在,創(chuàng)建新用戶并保存
            user = createUserWithPhone(phone);
        }
        	// 7. 保存用戶信息到 session 中(通過 BeanUtil.copyProperties 方法將 user 中的信息過濾到 UserDTO 上,即用來隱藏部分信息)
        session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));
        return Result.ok();
    }

    private User createUserWithPhone(String phone) {
        // 1. 創(chuàng)建用戶
        User user = new User();
        user.setPhone(phone);
        user.setNickName("user_" + RandomUtil.randomString(10));
        // 2. 保存用戶(這里使用 mybatis-plus)
        save(user);
        return user;
    }
}

1.4 實作登入校驗攔截器

登入校驗攔截器實作:

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 獲取 session
        HttpSession session = request.getSession();
        // 2. 獲取 session 中的用戶
        UserDTO user = (UserDTO) session.getAttribute("user");
        // 3. 判斷用戶是否存在
        if(user == null){
            // 4. 不存在,攔截,返回 401 未授權(quán)
            response.setStatus(401);
            return false;
        }
        // 5. 存在,保存用戶信息到 ThreadLocal
        UserHolder.saveUser(user);
        // 6. 放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 移除用戶,避免內(nèi)存泄露
        UserHolder.removeUser();
    }
}

UserHolder 類別的實作: 在該類別中定義了一個靜態(tài)的ThreadLocal

public class UserHolder {
    private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();

    public static void saveUser(UserDTO user){
        tl.set(user);
    }

    public static UserDTO getUser(){
        return tl.get();
    }

    public static void removeUser(){
        tl.remove();
    }
}

設(shè)定攔截器:

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .excludePathPatterns(
                        "/user/login",
                        "/user/code"
                );
    }
}

前端請求說明:

說明#要求方式POST請求路徑/user/me請求參數(shù)回傳值無

後端介面實作:

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Override
    public Result me() {
        UserDTO user = UserHolder.getUser();
        return Result.ok(user);
    }
}

2. 叢集的session 共享問題

session 共享問題:

多臺tomcat 並不會共用session 儲存空間,當(dāng)請求切換到不同tomcat 服務(wù)時會導(dǎo)致資料遺失的問題。

session 的替代方案應(yīng)該滿足以下條件:

  • 資料共享(不同的tomcat 都能夠存取Redis 中的資料)

  • 記憶體儲存(Redis 透過記憶體儲存)

  • key、value 結(jié)構(gòu)(Redis 是key-value 結(jié)構(gòu))

3. 基於Redis 實作共享session 登入

3.1 Redis 實作共享session 登入流程圖

Redis的分享session應(yīng)用如何實現(xiàn)簡訊登入

Redis的分享session應(yīng)用如何實現(xiàn)簡訊登入##3.2實作發(fā)送簡訊驗證碼

前端請求說明:

請求方式請求路徑請求參數(shù)返回值##後端介面實現(xiàn):
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Result sendCode(String phone, HttpSession session) {
        // 1. 校驗手機號
        if (RegexUtils.isPhoneInvalid(phone)) {
            // 2. 如果不符合,返回錯誤信息
            return Result.fail("手機號格式錯誤!");
        }
        // 3. 符合,生成驗證碼(設(shè)置生成6位)
        String code = RandomUtil.randomNumbers(6);
        // 4. 保存驗證碼到 Redis(以手機號為 key,設(shè)置有效期為 2min)
        stringRedisTemplate.opsForValue().set("login:code:" + phone, code, 2, TimeUnit.MINUTES);
        // 5. 發(fā)送驗證碼(這里并未實現(xiàn),通過日志記錄)
        log.debug("發(fā)送短信驗證碼成功,驗證碼:{}", code);
        // 返回 ok
        return Result.ok();
    }
}

說明
POST
/user/code
phone(電話號碼)
#無
3.3 實作簡訊驗證碼登入、註冊

前端請求說明:

##說明POST/user/loginphone(電話號碼);code(驗證碼)無後端介面實作:
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Override
    public Result login(LoginFormDTO loginForm, HttpSession session) {
        // 1. 校驗手機號
        String phone = loginForm.getPhone();
        if(RegexUtils.isPhoneInvalid(phone)){
            // 不一致,返回錯誤信息
            return Result.fail("手機號格式錯誤!");
        }
        // 2. 校驗驗證碼
        String cacheCode = (String) session.getAttribute("code");
        String code = loginForm.getCode();
        if(cacheCode == null || !cacheCode.equals(cacheCode)){
            // 不一致,返回錯誤信息
            return Result.fail("驗證碼錯誤!");
        }
        // 4. 一致,根據(jù)手機號查詢用戶(這里使用的 mybatis-plus)
        User user = query().eq("phone", phone).one();
        // 5. 判斷用戶是否存在
        if(user == null){
            // 6. 不存在,創(chuàng)建新用戶并保存
            user = createUserWithPhone(phone);
        }
        	// 7. 保存用戶信息到 session 中(通過 BeanUtil.copyProperties 方法將 user 中的信息過濾到 UserDTO 上,即用來隱藏部分信息)
        session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));
        return Result.ok();
    }

    private User createUserWithPhone(String phone) {
        // 1. 創(chuàng)建用戶
        User user = new User();
        user.setPhone(phone);
        user.setNickName("user_" + RandomUtil.randomString(10));
        // 2. 保存用戶(這里使用 mybatis-plus)
        save(user);
        return user;
    }
}
3.4 實作登入校驗攔截器

請求方式
#請求路徑
請求參數(shù)
傳回值

這裡將原有的一個攔截器分成兩個攔截器,第一個攔截器對所有的請求進行攔截,每次攔截刷新token 的有效期,並將能查詢到的用戶資訊保存到ThreadLocal 中。第二個攔截器則進行攔截功能,對需要登入的路徑進行攔截。

刷新token 攔截器實作:

public class RefreshTokenInterceptor implements HandlerInterceptor {

    private StringRedisTemplate stringRedisTemplate;

    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate){
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 獲取請求頭中的 token
        String token = request.getHeader("authorization");
        if (StrUtil.isBlank(token)) {
            return true;
        }
        // 2. 基于 token 獲取 redis 中的用戶
        String tokenKey = "login:token:" + token;
        Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(tokenKey);
        // 3. 判斷用戶是否存在
        if (userMap.isEmpty()) {
            return true;
        }
        // 5. 將查詢到的 Hash 數(shù)據(jù)轉(zhuǎn)為 UserDTO 對象
        UserDTO user = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);
        // 6. 存在,保存用戶信息到 ThreadLocal
        UserHolder.saveUser(user);
        // 7. 刷新 token 有效期 30 min
        stringRedisTemplate.expire(tokenKey, 30, TimeUnit.MINUTES);
        // 8. 放行
        return true;
    }
}

登入校驗攔截器實作:

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 獲取 session
        HttpSession session = request.getSession();
        // 2. 獲取 session 中的用戶
        UserDTO user = (UserDTO) session.getAttribute("user");
        // 3. 判斷用戶是否存在
        if(user == null){
            // 4. 不存在,攔截,返回 401 未授權(quán)
            response.setStatus(401);
            return false;
        }
        // 5. 存在,保存用戶信息到 ThreadLocal
        UserHolder.saveUser(user);
        // 6. 放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 移除用戶,避免內(nèi)存泄露
        UserHolder.removeUser();
    }
}

UserHolder 類別的實作: 在該類別中定義了一個靜態(tài)的ThreadLocal

public class UserHolder {
    private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();

    public static void saveUser(UserDTO user){
        tl.set(user);
    }

    public static UserDTO getUser(){
        return tl.get();
    }

    public static void removeUser(){
        tl.remove();
    }
}

設(shè)定攔截器:

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate))
                .addPathPatterns("/**").order(0);
        registry.addInterceptor(new LoginInterceptor())
                .excludePathPatterns(
                        "/user/login",
                        "/user/code"
                ).order(1);
    }
}

前端請求說明:

說明POST/user/me無無後端介面實現(xiàn):
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Override
    public Result me() {
        UserDTO user = UserHolder.getUser();
        return Result.ok(user);
    }
}

以上是Redis的分享session應(yīng)用如何實現(xiàn)簡訊登入的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

laravel8 的優(yōu)化點 laravel8 的優(yōu)化點 Apr 18, 2025 pm 12:24 PM

Laravel 8 針對性能優(yōu)化提供了以下選項:緩存配置:使用 Redis 緩存驅(qū)動、緩存門面、緩存視圖和頁面片段。數(shù)據(jù)庫優(yōu)化:建立索引、使用查詢範(fàn)圍、使用 Eloquent 關(guān)係。 JavaScript 和 CSS 優(yōu)化:使用版本控制、合併和縮小資產(chǎn)、使用 CDN。代碼優(yōu)化:使用 Composer 安裝包、使用 Laravel 助手函數(shù)、遵循 PSR 標(biāo)準(zhǔn)。監(jiān)控和分析:使用 Laravel Scout、使用 Telescope、監(jiān)控應(yīng)用程序指標(biāo)。

如何利用Redis緩存方案高效實現(xiàn)產(chǎn)品排行榜列表的需求? 如何利用Redis緩存方案高效實現(xiàn)產(chǎn)品排行榜列表的需求? Apr 19, 2025 pm 11:36 PM

Redis緩存方案如何實現(xiàn)產(chǎn)品排行榜列表的需求?在開發(fā)過程中,我們常常需要處理排行榜的需求,例如展示一個?...

Spring Boot中OAuth2Authorization對象Redis緩存失敗怎麼辦? Spring Boot中OAuth2Authorization對象Redis緩存失敗怎麼辦? Apr 19, 2025 pm 08:03 PM

SpringBoot中使用Redis緩存OAuth2Authorization對像在SpringBoot應(yīng)用中,使用SpringSecurityOAuth2AuthorizationServer...

Laravel 最佳擴展包推薦:2024 年必備工具 Laravel 最佳擴展包推薦:2024 年必備工具 Apr 30, 2025 pm 02:18 PM

2024年必備的Laravel擴展包包括:1.LaravelDebugbar,用於監(jiān)控和調(diào)試代碼;2.LaravelTelescope,提供詳細(xì)的應(yīng)用監(jiān)控;3.LaravelHorizon,管理Redis隊列任務(wù)。這些擴展包能提升開發(fā)效率和應(yīng)用性能。

Laravel 環(huán)境搭建與基礎(chǔ)配置(Windows/Mac/Linux) Laravel 環(huán)境搭建與基礎(chǔ)配置(Windows/Mac/Linux) Apr 30, 2025 pm 02:27 PM

在不同操作系統(tǒng)上搭建Laravel環(huán)境的步驟如下:1.Windows:使用XAMPP安裝PHP和Composer,配置環(huán)境變量,安裝Laravel。 2.Mac:使用Homebrew安裝PHP和Composer,安裝Laravel。 3.Linux:使用Ubuntu更新系統(tǒng),安裝PHP和Composer,安裝Laravel。每個系統(tǒng)的具體命令和路徑有所不同,但核心步驟一致,確保順利搭建Laravel開發(fā)環(huán)境。

REDIS的角色:探索數(shù)據(jù)存儲和管理功能 REDIS的角色:探索數(shù)據(jù)存儲和管理功能 Apr 22, 2025 am 12:10 AM

Redis在數(shù)據(jù)存儲和管理中扮演著關(guān)鍵角色,通過其多種數(shù)據(jù)結(jié)構(gòu)和持久化機製成為現(xiàn)代應(yīng)用的核心。 1)Redis支持字符串、列表、集合、有序集合和哈希表等數(shù)據(jù)結(jié)構(gòu),適用於緩存和復(fù)雜業(yè)務(wù)邏輯。 2)通過RDB和AOF兩種持久化方式,Redis確保數(shù)據(jù)的可靠存儲和快速恢復(fù)。

在多節(jié)點環(huán)境下,如何確保Spring Boot的@Scheduled定時任務(wù)只在一個節(jié)點上執(zhí)行? 在多節(jié)點環(huán)境下,如何確保Spring Boot的@Scheduled定時任務(wù)只在一個節(jié)點上執(zhí)行? Apr 19, 2025 pm 10:57 PM

SpringBoot定時任務(wù)在多節(jié)點環(huán)境下的優(yōu)化方案在開發(fā)Spring...

REDIS:了解其架構(gòu)和目的 REDIS:了解其架構(gòu)和目的 Apr 26, 2025 am 12:11 AM

Redis是一種內(nèi)存數(shù)據(jù)結(jié)構(gòu)存儲系統(tǒng),主要用作數(shù)據(jù)庫、緩存和消息代理。它的核心特點包括單線程模型、I/O多路復(fù)用、持久化機制、復(fù)制與集群功能。Redis在實際應(yīng)用中常用于緩存、會話存儲和消息隊列,通過選擇合適的數(shù)據(jù)結(jié)構(gòu)、使用管道和事務(wù)、以及進行監(jiān)控和調(diào)優(yōu),可以顯著提升其性能。

See all articles

    • 請求方式
      請求路徑
      請求參數(shù)
      傳回值

          <rp id="4j1a0"></rp>