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

SpringBoot整合redis實現(xiàn)輸入密碼錯誤限制登錄功能

 更新時間:2024年02月26日 11:13:28   作者:戴**  
遇到這樣的需求需要實現(xiàn)一個登錄功能,并且2分鐘之內(nèi)只能輸入5次錯誤密碼,若輸入五次之后還沒有輸入正確密碼,系統(tǒng)將會將該賬號鎖定1小時,這篇文章主要介紹了SpringBoot整合redis并實現(xiàn)輸入密碼錯誤限制登錄功能,需要的朋友可以參考下

需求:
實現(xiàn)一個登錄功能,并且2分鐘之內(nèi)只能輸入5次錯誤密碼,若輸入五次之后還沒有輸入正確密碼,系統(tǒng)將會將該賬號鎖定1小時

pom.xml

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
<!--        jedis 包-->
        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0</version>
        </dependency>
<!--springboot整合redis包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-configuration-processor</artifactId>-->
<!--            <optional>true</optional>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

yml配置

#redis
redis:
  #redis機器ip
  hostname: 127.0.0.1
  #redis端口
  port: 6379
  #redis密碼
  password:
  #redis超時時間(毫秒),如果不設(shè)置,取默認值2000
  timeout: 10000
  #最大空閑數(shù)
  maxIdle: 300
  #連接池的最大數(shù)據(jù)庫連接數(shù)。設(shè)為0表示無限制,如果是jedis 2.4以后用redis.maxTotal
  #maxActive=600
  #控制一個pool可分配多少個jedis實例,用來替換上面的redis.maxActive,如果是jedis 2.4以后用該屬性
  maxTotal: 1000
  #最大建立連接等待時間。如果超過此時間將接到異常。設(shè)為-1表示無限制。
  maxWaitMillis: 1000
  #連接的最小空閑時間 默認1800000毫秒(30分鐘)
  minEvictableIdleTimeMillis: 300000
  #每次釋放連接的最大數(shù)目,默認3
  numTestsPerEvictionRun: 1024
  #逐出掃描的時間間隔(毫秒) 如果為負數(shù),則不運行逐出線程, 默認-1
  timeBetweenEvictionRunsMillis: 30000
  #是否在從池中取出連接前進行檢驗,如果檢驗失敗,則從池中去除連接并嘗試取出另一個
  testOnBorrow: true
  #在空閑時檢查有效性, 默認false
  testWhileIdle: true
  #redis集群配置
  #spring.cluster.nodes=192.168.1.1:7001,192.168.1.1:7002,192.168.1.1:7003,192.168.1.1:7004,192.168.1.1:7005,192.168.1.1:7006
  #spring.cluster.max-redirects=3
  #哨兵模式
  #sentinel.host1=192.168.1.1
  #sentinel.port1=26379
#sentinel.host2=192.168.1.2
#sentinel.port2=26379
spring:
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    encoding: UTF-8
    mode: HTML5
    servlet:

bean層:

package com.springbootandredis.springbootredis.bean;
public class User {
    String username;
    String password;
    public User() {
    }
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

config 配置類

package com.springbootandredis.springbootredis.config;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.Serializable;
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Serializable> template = new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

controller

package com.springbootandredis.springbootredis.controller;
import com.springbootandredis.springbootredis.Service.ServiceImpl.GetMessageImpl;
import com.springbootandredis.springbootredis.Service.ServiceImpl.LoginServiceImpl;
import com.springbootandredis.springbootredis.bean.User;
import org.hibernate.validator.constraints.pl.REGON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Controller
public class userlogin {
    @Autowired
    LoginServiceImpl loginService;
    @Autowired
    GetMessageImpl getMessage;
    @ResponseBody
    @RequestMapping("/login")
    public String login(HttpServletRequest request) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = new User(username, password);
        Map<String, Object> map = loginService.loginUserLock(user);   //登錄 驗證第一層  看用戶是否被限制登錄
        if ((Boolean) map.get("flag")) {   //如果為true表示被限制登錄
            return "登錄失敗,因" + username + "超過了限制登錄次數(shù),已被禁止登錄.還剩" + map.get("lockTime") + "分鐘";
        } else {   //表示沒有被限制登錄   執(zhí)行 下一步登錄邏輯
            User user1 = loginService.login(user);  //執(zhí)行登錄功能
            if (user1 != null) {   //表示密碼正確  登錄成功
                /**
                 * 清空對應(yīng)的所有key
                 */
                loginService.DeleteMemory(getMessage.getLoginCountFailKey(user));
                loginService.DeleteMemory(getMessage.getLoginTimeLockKey(user));
                loginService.DeleteMemory(getMessage.getKeyName(user));
                return "登錄成功";
            } else {  //登錄不成功   計入登錄此時 等邏輯操作
                return loginService.loginValdate(user);
            }
        }
    }
    @RequestMapping("/tologin")
    public String tologin() {
        return "login";
    }
}

service interface

package com.springbootandredis.springbootredis.Service;
import com.springbootandredis.springbootredis.bean.User;
public interface GetMessage {
    String getKeyName(User user);
    String getLoginTimeLockKey(User user);
    String getLoginCountFailKey(User user);
}
/************分界線***********************************/
package com.springbootandredis.springbootredis.Service;
import com.springbootandredis.springbootredis.bean.User;
import java.util.Map;
public interface LoginService {
    /**
     * 驗證用戶登錄的賬號和密碼
     * @param user
     * @return
     */
    User login(User user);
    /**
     * 用戶在2分鐘內(nèi) 僅允許輸入錯誤密碼五次,如果超過次數(shù),限制其登錄一小時
     *
     * 給用戶詳細信息提示
     * @param user
     * @return
     */
    String loginValdata(User user);
    /**
     * 判斷當前的登錄用戶是否被限制登錄
     * @param user
     * @return
     */
    Map<String,Object> loginUserLock(User user);
    /**
     * 登錄不成功的操作(密碼錯誤)
     * @param user
     * @return
     */
    String loginValdate(User user);
    /**
     * 刪除登錄失敗所存入的鍵值對
     * @param key
     * @return
     */
    Boolean DeleteMemory(String key);
}

service impl

package com.springbootandredis.springbootredis.Service.ServiceImpl;
import com.springbootandredis.springbootredis.Service.GetMessage;
import com.springbootandredis.springbootredis.bean.User;
import org.springframework.stereotype.Service;
@Service
public class GetMessageImpl implements GetMessage {
    @Override
    public String getKeyName(User user) {
        return "user:"+user.getUsername();
    }
    @Override
    public String getLoginTimeLockKey(User user) {
        return "user:loginTime:lock:"+user.getUsername();
    }
    @Override
    public String getLoginCountFailKey(User user) {
        return "user:loginCount:fail:"+user.getUsername();
    }
}
/******************************************分界線*************************************/
package com.springbootandredis.springbootredis.Service.ServiceImpl;
import com.springbootandredis.springbootredis.Service.LoginService;
import com.springbootandredis.springbootredis.bean.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    GetMessageImpl getMessage;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    /**
     * 驗證用戶是密碼是否正確
     *
     * @param user
     * @return
     */
    @Override
    public User login(User user) {
        if (user.getUsername().equals("dlf")) {      //模仿從數(shù)據(jù)庫中根據(jù)username查詢密碼  然后驗證密碼是否正確
            if (user.getPassword().equals("dlf")) {
                return user;
            }
        }
        return null;
    }
    @Override
    public String loginValdata(User user) {
        return null;
    }
    /**
     * 判斷當前登錄的用戶是否被限制登錄
     * 查詢當前key是否存在,如果存在,就被限制,注意:需要給用戶做提示:您當前的用戶已被限制,還剩多長時間
     * 如果不存在就不被限制
     *
     * @param user
     * @return
     */
    @Override
    public Map<String, Object> loginUserLock(User user) {
        Map<String, Object> map = new HashMap<>();
        if (stringRedisTemplate.hasKey(getMessage.getLoginTimeLockKey(user))) {
            //如果存在就是用戶已經(jīng)輸錯了密碼五次 被鎖定了倆小時
            map.put("flag", true);  //表示用戶已經(jīng)被鎖定
            map.put("lockTime", stringRedisTemplate.getExpire(getMessage.getLoginTimeLockKey(user), TimeUnit.MINUTES));     //得到被鎖定之后還剩下多少時間  以分鐘返回
        } else {
            map.put("flag", false);   //flag 為false 表示用戶沒有被限制
        }
        return map;
    }
    /**
     * 登錄失敗的相應(yīng)操作(密碼錯誤)
     *
     * @param user
     * @return
     */
    @Override
    public String loginValdate(User user) {
        Integer num = 5;
        //記錄登錄錯誤次數(shù)的key
        String key = getMessage.getLoginCountFailKey(user);
        if (!stringRedisTemplate.hasKey(key)) {   //如果不存在
            //是第一次登錄失敗 次數(shù)為1
            // userlogincountfile;用戶名進行賦值   同時設(shè)置失效期2分鐘
            stringRedisTemplate.opsForValue().set(key, "1", 2, TimeUnit.MINUTES);
            return "登錄失敗,在2分鐘內(nèi)還允許輸入錯誤" + (num - 1) + "次";
        } else {
            //如果存在
            //查詢登錄失敗次數(shù)
            long loginFilCount = Long.parseLong(stringRedisTemplate.opsForValue().get(key));
            if (loginFilCount < (num - 1)) {    //代表當前如果登錄次數(shù)小于4  意思:還有資格繼續(xù)進行登錄
                //登錄次數(shù)+1
                stringRedisTemplate.opsForValue().increment(key, 1);
                long secends = stringRedisTemplate.getExpire(key, TimeUnit.SECONDS);  //返回的是秒
                return user.getUsername() + "登錄失敗,在" + secends + "秒內(nèi)還允許輸入錯誤" + (num - loginFilCount - 1) + "次";
            } else {   //超過了指定的登錄次數(shù)
                String lockkey = getMessage.getLoginTimeLockKey(user);
                stringRedisTemplate.opsForValue().set(lockkey, "1", 1, TimeUnit.HOURS);
                return "因登錄失敗此時超過" + num + "次,以對其限制登錄1小時";
            }
        }
    }
    @Override
    public Boolean DeleteMemory(String key) {
        try {
            stringRedisTemplate.delete(key);
        } catch (Exception e) {
            return false;
        }
        return true;
    }
}

到此這篇關(guān)于SpringBoot整合redis并實現(xiàn)輸入密碼錯誤限制登錄功能的文章就介紹到這了,更多相關(guān)SpringBoot redis輸入密碼錯誤限制登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 終止線程的4種方式小結(jié)

    java 終止線程的4種方式小結(jié)

    本文主要介紹了java終止線程的4種方式小結(jié),包含布爾標志位,interrupt()方法,stop()方法和Thread.interrupt()方法,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • 淺談IDEA2018打包可執(zhí)行jar包的流程

    淺談IDEA2018打包可執(zhí)行jar包的流程

    這篇文章主要介紹了淺談IDEA2018打包可執(zhí)行jar包的流程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • spring aop之@AfterReturning不生效問題及解決

    spring aop之@AfterReturning不生效問題及解決

    這篇文章主要介紹了spring aop之@AfterReturning不生效問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Spring BeanFactory和FactoryBean區(qū)別解析

    Spring BeanFactory和FactoryBean區(qū)別解析

    這篇文章主要介紹了Spring BeanFactory和FactoryBean區(qū)別解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • Java初學(xué)者了解

    Java初學(xué)者了解"=="與equals的區(qū)別

    這篇文章主要介紹了Java初學(xué)者了解"=="與equals的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • Java 實現(xiàn)RSA非對稱加密算法

    Java 實現(xiàn)RSA非對稱加密算法

    RSA解決了對稱加密的一個不足,比如AES算法加密和解密時使用的是同一個秘鑰,因此這個秘鑰不能公開,因此對于需要公開秘鑰的場合,我們需要在加密和解密過程中使用不同的秘鑰,加密使用的公鑰可以公開,解密使用的私鑰要保密,這就是非對稱加密的好處?!?/div> 2021-06-06
  • Java泛型映射不同的值類型詳解及實例代碼

    Java泛型映射不同的值類型詳解及實例代碼

    這篇文章主要介紹了Java泛型映射不同的值類型詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • SpringBoot線程池ThreadPoolTaskExecutor異步處理百萬級數(shù)據(jù)

    SpringBoot線程池ThreadPoolTaskExecutor異步處理百萬級數(shù)據(jù)

    本文主要介紹了SpringBoot線程池ThreadPoolTaskExecutor異步處理百萬級數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • RequestContextHolder.getRequestAttributes()空指針問題及解決

    RequestContextHolder.getRequestAttributes()空指針問題及解決

    這篇文章主要介紹了RequestContextHolder.getRequestAttributes()空指針問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • JAVA中關(guān)于多線程的使用詳解

    JAVA中關(guān)于多線程的使用詳解

    本文給大家介紹JAVA中關(guān)于多線程的使用詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-09-09

最新評論

伊通| 沧源| 翁牛特旗| 太湖县| 长白| 开封县| 乌海市| 兰考县| 堆龙德庆县| 余干县| 泸定县| 鄂托克前旗| 洛浦县| 神池县| 大田县| 黄石市| 西华县| 红安县| 西峡县| 文成县| 凉城县| 齐齐哈尔市| 泸溪县| 金溪县| 阜宁县| 方山县| 屯门区| 封开县| 鄂伦春自治旗| 桐柏县| 齐齐哈尔市| 珲春市| 五家渠市| 稻城县| 扎鲁特旗| 伊吾县| 山东省| 三都| 安化县| 河北省| 富顺县|