首页 > 编程 > Java > 正文

SpringBoot下token短信验证登入登出权限操作(token存放redis,ali短信接口)

2019-11-26 08:21:37
字体:
来源:转载
供稿:网友

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数据即可,

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表