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

SpringBoot下token短信验证登入登出(token存放redis)

不对SpringBoot进行介绍,具体的可以参考官方文档
介绍:token基本使用,redis基本使用

思路:获取短信(验证并限制发送次数,将code存放redis)-->登入(验证并限制错误次数,将用户信息及权限放token,token放redis)-->查询操作(略),主要将前两点,不足的希望指出,谢谢

步骤:
1.整合Redis需要的依赖,yml自行配置,ali短信接口依赖(使用引入外部包的方式)


    org.springframework.boot
    spring-boot-starter-data-redis


    ali
    taobao-sdk-java-auto
    system
    
    ${project.basedir}/libs/taobao-sdk-java-auto.jar

.......

        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                    true
                
            
        
    

2.ali短信接口工具类,发送验证码

@Autowired
    private StringRedisTemplate redisTemplate;
....略....
//查询是否有此用户,记录单位时间内发送短信次数,并限制发送次数
Account account = accountService.findByUserName(phone);
if (account==null){
 return ResultVOUtil.erro(0,"未注册用户");
  }
ValueOperations 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 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 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 audience = jwt.getAudience();
            Map claims = jwt.getClaims();
            Claim limits = claims.get("limits");
            //验证操作权限,set长度改变说明权限不一致
            String ss = limits.asString();
            String[] split = ss.split(",");
            Set 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数据即可,

你可能感兴趣的:(java技术,springboot,token,redis,ali短信)