经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Redis » 查看文章
SpringBoot下token短信验证登入登出权限操作(token存放redis,ali短信接口)
来源:jb51  时间:2019/11/12 13:32:32  对本文有异议

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

不对SpringBoot进行介绍,具体的可以参考官方文档

介绍:token基本使用,redis基本使用

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

步骤:

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

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>ali</groupId>
  7. <artifactId>taobao-sdk-java-auto</artifactId>
  8. <scope>system</scope>
  9. <!--将jar包放在项目/libs/xxx.jar-->
  10. <systemPath>${project.basedir}/libs/taobao-sdk-java-auto.jar</systemPath>
  11. </dependency>
  12. .......
  13. <build>
  14. <plugins>
  15. <plugin>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-maven-plugin</artifactId>
  18. </plugin>
  19. <plugin>
  20. <groupId>org.springframework.boot</groupId>
  21. <artifactId>spring-boot-maven-plugin</artifactId>
  22. <configuration>
  23. <!--打包的时候引用该属性的包-->
  24. <includeSystemScope>true</includeSystemScope>
  25. </configuration>
  26. </plugin>
  27. </plugins>
  28. </build>

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

  1. @Autowired
  2. private StringRedisTemplate redisTemplate;
  3. ....略....
  4. //查询是否有此用户,记录单位时间内发送短信次数,并限制发送次数
  5. Account account = accountService.findByUserName(phone);
  6. if (account==null){
  7. return ResultVOUtil.erro(0,"未注册用户");
  8. }
  9. ValueOperations<String, String> ops = redisTemplate.opsForValue();
  10. String getTimes = ops.get(account + "code");
  11. Integer gts=getTimes==null?0:Integer.valueOf(getTimes);
  12. if (gts>5){
  13. return ResultVOUtil.erro(0,"获取短信次数过多,请稍后再试");
  14. }
  15. ops.set(account+"code",String.valueOf(gts+1),5,TimeUnit.MINUTES);
  16. NoteUtils noteUtils=new NoteUtils();
  17. String validCode = UidUtil.getValidCode(); //生成随机数
  18. try {
  19. String yzmcode = noteUtils.yzmcode(validCode, phone);
  20. //redis设置验证码有效时间5分组
  21. ops.set(phone,validCode,5,TimeUnit.MINUTES);
  22. }catch (Exception e){
  23. throw new YunExceptions(0,"获取验证码服务器bug");
  24. }
  25. //短信接口工具类
  26. public class NoteUtils {
  27. //仅当示例:具体参考官方文档
  28. public String url="***************";
  29. public String appkey="****************";
  30. public String secret="*********************";
  31. public String yzmcode(String code,String telnum) throws ApiException, JSONException {
  32. TaobaoClient client = new DefaultTaobaoClient(url, appkey, secret);
  33. AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
  34. req.setExtend( "extend" );
  35. req.setSmsType( "normal" );
  36. req.setSmsFreeSignName( "*************" );
  37. req.setSmsParamString( "{code:'"+code+"'}" );
  38. req.setRecNum(telnum);
  39. req.setSmsTemplateCode( "******************" );
  40. AlibabaAliqinFcSmsNumSendResponse rsp = client.execute(req);
  41. return "true";
  42. }
  43. }

3.登入验证,并将权限保存在token,以下有token工具类,可直接copy使用

  1. public ResultVo login(String phone, String code, HttpServletResponse response, HttpServletRequest request){
  2. ValueOperations<String, String> ops = redisTemplate.opsForValue();
  3. String validcode = ops.get(phone);
  4. String outtimes=ops.get(phone+"wrong");
  5. Integer ots=outtimes==null?0:Integer.valueOf(outtimes);
  6. if (ots>5){
  7. return ResultVOUtil.erro(0,"错误次数过多,请稍后再试");
  8. }
  9. if (validcode!=null){
  10. String vcode=validcode.toString();
  11. if (code.equalsIgnoreCase(vcode)){
  12. Account account = accountService.findByUserName(phone);
  13. if (account!=null){
  14. //记录登入信息,获取权限,字符串类型a,b,c,d
  15. String token = TokenUtils.tokenGet(phone, account.getDbids());
  16. Loglogin loglogin=new Loglogin();
  17. loglogin.setActionid(200);
  18. loglogin.setUserip(request.getRemoteAddr());
  19. loglogin.setUsername(phone);
  20. loglogin.setLogtime(Timestamp.valueOf(TimeUtil.getCurDate()));
  21. loglogin.setUserid(account.getUserId());
  22. logloginService.save(loglogin);
  23. 设置token时效
  24. ops.set(phone+"token",token,60,TimeUnit.MINUTES);
  25. return ResultVOUtil.success(token);
  26. }else {
  27. return ResultVOUtil.erro(0,"没有此账户");
  28. }
  29. }else {
  30. ops.set(phone+"wrong",String.valueOf(ots+1),5,TimeUnit.MINUTES);
  31. return ResultVOUtil.erro(0,"验证码错误");
  32. }
  33. }else {
  34. return ResultVOUtil.erro(0,"请先获取验证码");
  35. }
  36. }
  37. //token工具类
  38. public class TokenUtils {
  39. public static String tokenGet(String username,String limits){
  40. Map<String,Object> map=new HashMap<>();
  41. map.put("alg","HS256");
  42. map.put("typ","JWT");
  43. try {
  44. Algorithm algorithm=Algorithm.HMAC256("*******");
  45. String token = JWT.create()
  46. .withHeader(map)
  47. /*设置 载荷 Payload*/
  48. .withClaim("loginName", username)
  49. .withClaim("limits",limits)
  50. //设置过期时间-->间隔一定时间验证是否本人登入
  51. .withExpiresAt(new Date(System.currentTimeMillis()+3600000*5))
  52. .withIssuer("****")//签名是有谁生成 例如 服务器
  53. .withSubject("*****")//签名的主题
  54. .withAudience("*****")//签名的观众 也可以理解谁接受签名的
  55. /*签名 Signature */
  56. .sign(algorithm);
  57. return token;
  58. }catch (Exception e){
  59. e.printStackTrace();
  60. }
  61. return null;
  62. }
  63. public static String validToken(String token, String dbid){
  64. try {
  65. Algorithm algorithm = Algorithm.HMAC256("*******");
  66. JWTVerifier verifier = JWT.require(algorithm)
  67. .withIssuer("SERVICE")
  68. .build();
  69. DecodedJWT jwt = verifier.verify(token);
  70. String subject = jwt.getSubject();
  71. List<String> audience = jwt.getAudience();
  72. Map<String, Claim> claims = jwt.getClaims();
  73. Claim limits = claims.get("limits");
  74. //验证操作权限,set长度改变说明权限不一致
  75. String ss = limits.asString();
  76. String[] split = ss.split(",");
  77. Set<String> set=new HashSet<>(Arrays.asList(split));
  78. int size = set.size();
  79. set.add(dbid);
  80. if (set.size()!=size){
  81. return null;
  82. }else {
  83. Claim name = claims.get("loginName");
  84. return name.asString();
  85. }
  86. }catch (Exception e){
  87. e.printStackTrace();
  88. }
  89. return null;
  90. }

4.接下来都比较简单

4.1获取数据-->前端传参数,后台验证即可,

4.2退出的时候,清除redis里的token数据即可,

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号