SpringBoot下token短信验证登入登出(token存放redis)
不对SpringBoot进行介绍,具体的可以参考官方文档
介绍:token基本使用,redis基本使用
思路:获取短信(验证并限制发送次数,将code存放redis)-->登入(验证并限制错误次数,将用户信息及权限放token,token放redis)-->查询操作(略),主要将前两点,不足的希望指出,谢谢
步骤:
1.整合Redis需要的依赖,yml自行配置,ali短信接口依赖(使用引入外部包的方式)
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
- <dependency>
- <groupId>ali</groupId>
- <artifactId>taobao-sdk-java-auto</artifactId>
- <scope>system</scope>
- <!--将jar包放在项目/libs/xxx.jar-->
- <systemPath>${project.basedir}/libs/taobao-sdk-java-auto.jar</systemPath>
- </dependency>
- .......
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <configuration>
- <!--打包的时候引用该属性的包-->
- <includeSystemScope>true</includeSystemScope>
- </configuration>
- </plugin>
- </plugins>
- </build>
2.ali短信接口工具类,发送验证码
- @Autowired
- private StringRedisTemplate redisTemplate;
- ....略....
- //查询是否有此用户,记录单位时间内发送短信次数,并限制发送次数
- Account account = accountService.findByUserName(phone);
- if (account==null){
- return ResultVOUtil.erro(0,"未注册用户");
- }
- ValueOperations<String, String> ops = redisTemplate.opsForValue();
- String getTimes = ops.get(account + "code");
- Integer gts=getTimes==null?0:Integer.valueOf(getTimes);
- if (gts>5){
- return ResultVOUtil.erro(0,"获取短信次数过多,请稍后再试");
- }
- ops.set(account+"code",String.valueOf(gts+1),5,TimeUnit.MINUTES);
- NoteUtils noteUtils=new NoteUtils();
- String validCode = UidUtil.getValidCode(); //生成随机数
- try {
- String yzmcode = noteUtils.yzmcode(validCode, phone);
- //redis设置验证码有效时间5分组
- ops.set(phone,validCode,5,TimeUnit.MINUTES);
- }catch (Exception e){
- throw new YunExceptions(0,"获取验证码服务器bug");
- }
-
- //短信接口工具类
- public class NoteUtils {
- //仅当示例:具体参考官方文档
- public String url="***************";
- public String appkey="****************";
- public String secret="*********************";
- public String yzmcode(String code,String telnum) throws ApiException, JSONException {
- TaobaoClient client = new DefaultTaobaoClient(url, appkey, secret);
- AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
- req.setExtend( "extend" );
- req.setSmsType( "normal" );
- req.setSmsFreeSignName( "*************" );
- req.setSmsParamString( "{code:'"+code+"'}" );
- req.setRecNum(telnum);
- req.setSmsTemplateCode( "******************" );
- AlibabaAliqinFcSmsNumSendResponse rsp = client.execute(req);
- return "true";
-
- }
- }
3.登入验证,并将权限保存在token,以下有token工具类,可直接copy使用
- public ResultVo login(String phone, String code, HttpServletResponse response, HttpServletRequest request){
- ValueOperations<String, String> ops = redisTemplate.opsForValue();
- String validcode = ops.get(phone);
- String outtimes=ops.get(phone+"wrong");
- Integer ots=outtimes==null?0:Integer.valueOf(outtimes);
- if (ots>5){
- return ResultVOUtil.erro(0,"错误次数过多,请稍后再试");
- }
- if (validcode!=null){
- String vcode=validcode.toString();
- if (code.equalsIgnoreCase(vcode)){
- Account account = accountService.findByUserName(phone);
- if (account!=null){
- //记录登入信息,获取权限,字符串类型a,b,c,d
- String token = TokenUtils.tokenGet(phone, account.getDbids());
- Loglogin loglogin=new Loglogin();
- loglogin.setActionid(200);
- loglogin.setUserip(request.getRemoteAddr());
- loglogin.setUsername(phone);
- loglogin.setLogtime(Timestamp.valueOf(TimeUtil.getCurDate()));
- loglogin.setUserid(account.getUserId());
- logloginService.save(loglogin);
- 设置token时效
- ops.set(phone+"token",token,60,TimeUnit.MINUTES);
- return ResultVOUtil.success(token);
- }else {
- return ResultVOUtil.erro(0,"没有此账户");
- }
- }else {
- ops.set(phone+"wrong",String.valueOf(ots+1),5,TimeUnit.MINUTES);
- return ResultVOUtil.erro(0,"验证码错误");
- }
- }else {
- return ResultVOUtil.erro(0,"请先获取验证码");
- }
- }
- //token工具类
- public class TokenUtils {
- public static String tokenGet(String username,String limits){
- Map<String,Object> map=new HashMap<>();
- map.put("alg","HS256");
- map.put("typ","JWT");
- try {
- Algorithm algorithm=Algorithm.HMAC256("*******");
- String token = JWT.create()
- .withHeader(map)
- /*设置 载荷 Payload*/
- .withClaim("loginName", username)
- .withClaim("limits",limits)
- //设置过期时间-->间隔一定时间验证是否本人登入
- .withExpiresAt(new Date(System.currentTimeMillis()+3600000*5))
- .withIssuer("****")//签名是有谁生成 例如 服务器
- .withSubject("*****")//签名的主题
- .withAudience("*****")//签名的观众 也可以理解谁接受签名的
- /*签名 Signature */
- .sign(algorithm);
- return token;
- }catch (Exception e){
- e.printStackTrace();
- }
- return null;
- }
-
- public static String validToken(String token, String dbid){
- try {
- Algorithm algorithm = Algorithm.HMAC256("*******");
- JWTVerifier verifier = JWT.require(algorithm)
- .withIssuer("SERVICE")
- .build();
- DecodedJWT jwt = verifier.verify(token);
- String subject = jwt.getSubject();
- List<String> audience = jwt.getAudience();
- Map<String, Claim> claims = jwt.getClaims();
- Claim limits = claims.get("limits");
- //验证操作权限,set长度改变说明权限不一致
- String ss = limits.asString();
- String[] split = ss.split(",");
- Set<String> set=new HashSet<>(Arrays.asList(split));
- int size = set.size();
- set.add(dbid);
- if (set.size()!=size){
- return null;
- }else {
- Claim name = claims.get("loginName");
- return name.asString();
- }
- }catch (Exception e){
- e.printStackTrace();
- }
- return null;
- }
4.接下来都比较简单
4.1获取数据-->前端传参数,后台验证即可,
4.2退出的时候,清除redis里的token数据即可,
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。