用户管理
老规矩 先新建用户模块
这里没有客户端模块 是因为用户模块是一个单独的模块 不用服务之间的调用
导入总的依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 1<dependencies>
2
3 <!--所有provider公共依賴-->
4 <dependency>
5 <groupId>org.leryoo</groupId>
6 <artifactId>hrm-user-common</artifactId>
7 <version>1.0-SNAPSHOT</version>
8 </dependency>
9 <dependency>
10 <groupId>org.springframework.boot</groupId>
11 <artifactId>spring-boot-starter-web</artifactId>
12 </dependency>
13 <dependency>
14 <groupId>org.springframework.boot</groupId>
15 <artifactId>spring-boot-starter-test</artifactId>
16 <scope>test</scope>
17 </dependency>
18 <!-- Eureka 客户端依赖 -->
19 <dependency>
20 <groupId>org.springframework.cloud</groupId>
21 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
22 </dependency>
23
24 <!--配置中心支持-->
25 <dependency>
26 <groupId>org.springframework.cloud</groupId>
27 <artifactId>spring-cloud-starter-config</artifactId>
28 </dependency>
29
30
31 <!--mybatis-plus支持-->
32 <dependency>
33 <groupId>com.baomidou</groupId>
34 <artifactId>mybatis-plus-boot-starter</artifactId>
35 <version>2.2.0</version>
36 </dependency>
37
38 <!--数据库支持-->
39 <dependency>
40 <groupId>mysql</groupId>
41 <artifactId>mysql-connector-java</artifactId>
42 </dependency>
43
44 <dependency>
45 <groupId>io.springfox</groupId>
46 <artifactId>springfox-swagger2</artifactId>
47 <version>2.9.2</version>
48 </dependency>
49 <dependency>
50 <groupId>io.springfox</groupId>
51 <artifactId>springfox-swagger-ui</artifactId>
52 <version>2.9.2</version>
53 </dependency>
54
55 <dependency>
56 <groupId>org.leryoo</groupId>
57 <artifactId>hrm-common-client</artifactId>
58 <version>1.0-SNAPSHOT</version>
59 </dependency>
60
61</dependencies>
62
63
service依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 1<dependencies>
2 <!--所有provider公共依賴-->
3 <dependency>
4 <groupId>org.leryoo</groupId>
5 <artifactId>hrm-course-common</artifactId>
6 <version>1.0-SNAPSHOT</version>
7 </dependency>
8 <dependency>
9 <groupId>org.springframework.boot</groupId>
10 <artifactId>spring-boot-starter-web</artifactId>
11 </dependency>
12
13 <dependency>
14 <groupId>org.springframework.boot</groupId>
15 <artifactId>spring-boot-starter-test</artifactId>
16 <scope>test</scope>
17 </dependency>
18 <!-- Eureka 客户端依赖 -->
19 <dependency>
20 <groupId>org.springframework.cloud</groupId>
21 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
22 </dependency>
23
24 <!--配置中心支持-->
25 <dependency>
26 <groupId>org.springframework.cloud</groupId>
27 <artifactId>spring-cloud-starter-config</artifactId>
28 </dependency>
29
30 <dependency>
31 <groupId>io.springfox</groupId>
32 <artifactId>springfox-swagger2</artifactId>
33 <version>2.9.2</version>
34 </dependency>
35 <dependency>
36 <groupId>io.springfox</groupId>
37 <artifactId>springfox-swagger-ui</artifactId>
38 <version>2.9.2</version>
39 </dependency>
40
41 <!--mybatis-plus支持-->
42 <dependency>
43 <groupId>com.baomidou</groupId>
44 <artifactId>mybatis-plus-boot-starter</artifactId>
45 <version>2.2.0</version>
46 </dependency>
47
48 <!--数据库支持-->
49 <dependency>
50 <groupId>mysql</groupId>
51 <artifactId>mysql-connector-java</artifactId>
52 </dependency>
53 <!-- 通过feign调用client-->
54 <dependency>
55 <groupId>org.leryoo</groupId>
56 <artifactId>hrm-common-client</artifactId>
57 <version>1.0-SNAPSHOT</version>
58 </dependency>
59</dependencies>
60
61
但是这里也需要加上@EnableFeignClients注释 因为我们还需要调用其他服务
配置文件
和之前的一样 没啥两样的
用户的注册
图片验证码
我们首先做一下页面中图片验证码:
执行流程
如果是
单体项目 流程非常简单(session统一)
1
2
3
4
5 1 后台生成验证码放入session
2 后台把验证码写入图片,把图片以流的方式返回给用户
3 用户根据图片输入验证码,后台获取到后从seession获取出来做比对
4
5
参考文章:
https://www.cnblogs.com/nanyangke-cjz/p/7049281.html
如果是
前后端分离项目 就不能使用session
关于base64
https://www.cnblogs.com/x-st/p/5220282.html
前端准备
这里我们依然是使用live-server
live-server –port=6003
我们现在网页中设置钩子方法 当页面加载就去获取图片验证码的图片
后端代码
Controller层
service层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 1@Override
2publicString getImageCode(String imageCodeKey) {
3 try{
4 // 1 生成随机验证码 123456
5 String imageCode = VerifyCodeUtils
6 .generateVerifyCode(6).toLowerCase();
7 // 2 以imageCodeKey作为key存放验证到redis 5分钟过期
8 redisClient.addForTime(imageCodeKey,imageCode,60*5);
9 // 2 生成图片验证码图片 util
10 ByteArrayOutputStream data = new ByteArrayOutputStream();
11 VerifyCodeUtils.outputImage(100, 40, data, imageCode);
12 // 3 图片通过base64加密返回
13 BASE64Encoder encoder = new BASE64Encoder();
14 return encoder.encode(data.toByteArray());
15 }catch (Exception e){
16 e.printStackTrace();
17 }
18 return null;
19
20}
21
22
生成验证码的工具类
VerifyCodeUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220 1package org.leryoo.util;
2
3import sun.misc.BASE64Encoder;
4
5import javax.imageio.ImageIO;
6import java.awt.*;
7import java.awt.geom.AffineTransform;
8import java.awt.image.BufferedImage;
9import java.io.ByteArrayOutputStream;
10import java.io.IOException;
11import java.io.OutputStream;
12import java.util.Arrays;
13import java.util.Random;
14
15/**
16 * Created by
17 * on 2018/5/11
18 */
19public class VerifyCodeUtils {
20 //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
21 public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
22 private static Random random = new Random();
23
24
25 /**
26 * 使用系统默认字符源生成验证码
27 *
28 * @param verifySize 验证码长度
29 * @return
30 */
31 public static String generateVerifyCode(int verifySize) {
32 return generateVerifyCode(verifySize, VERIFY_CODES);
33 }
34
35 /**
36 * 使用指定源生成验证码
37 *
38 * @param verifySize 验证码长度
39 * @param sources 验证码字符源
40 * @return
41 */
42 public static String generateVerifyCode(int verifySize, String sources) {
43 if (sources == null || sources.length() == 0) {
44 sources = VERIFY_CODES;
45 }
46 int codesLen = sources.length();
47 Random rand = new Random(System.currentTimeMillis());
48 StringBuilder verifyCode = new StringBuilder(verifySize);
49 for (int i = 0; i < verifySize; i++) {
50 verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
51 }
52 return verifyCode.toString();
53 }
54
55 /**
56 * 输出指定验证码图片流
57 *
58 */
59 public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
60 int verifySize = code.length();
61 BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
62 Random rand = new Random();
63 Graphics2D g2 = image.createGraphics();
64 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
65 Color[] colors = new Color[5];
66 Color[] colorSpaces = new Color[]{Color.WHITE, Color.CYAN,
67 Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
68 Color.PINK, Color.YELLOW};
69 float[] fractions = new float[colors.length];
70 for (int i = 0; i < colors.length; i++) {
71 colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
72 fractions[i] = rand.nextFloat();
73 }
74 Arrays.sort(fractions);
75
76 g2.setColor(Color.GRAY);// 设置边框色
77 g2.fillRect(0, 0, w, h);
78
79 Color c = getRandColor(200, 250);
80 g2.setColor(c);// 设置背景色
81 g2.fillRect(0, 2, w, h - 4);
82
83 //绘制干扰线
84 Random random = new Random();
85 g2.setColor(getRandColor(160, 200));// 设置线条的颜色
86 for (int i = 0; i < 20; i++) {
87 int x = random.nextInt(w - 1);
88 int y = random.nextInt(h - 1);
89 int xl = random.nextInt(6) + 1;
90 int yl = random.nextInt(12) + 1;
91 g2.drawLine(x, y, x + xl + 40, y + yl + 20);
92 }
93
94 // 添加噪点
95 float yawpRate = 0.05f;// 噪声率
96 int area = (int) (yawpRate * w * h);
97 for (int i = 0; i < area; i++) {
98 int x = random.nextInt(w);
99 int y = random.nextInt(h);
100 int rgb = getRandomIntColor();
101 image.setRGB(x, y, rgb);
102 }
103
104 shear(g2, w, h, c);// 使图片扭曲
105
106 g2.setColor(getRandColor(100, 160));
107 int fontSize = h - 4;
108 Font font = new Font("Algerian", Font.ITALIC, fontSize);
109 g2.setFont(font);
110 char[] chars = code.toCharArray();
111 for (int i = 0; i < verifySize; i++) {
112 AffineTransform affine = new AffineTransform();
113 affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize / 2, h / 2);
114 g2.setTransform(affine);
115 g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
116 }
117
118 g2.dispose();
119 ImageIO.write(image, "jpg", os);
120 }
121
122 private static Color getRandColor(int fc, int bc) {
123 if (fc > 255)
124 fc = 255;
125 if (bc > 255)
126 bc = 255;
127 int r = fc + random.nextInt(bc - fc);
128 int g = fc + random.nextInt(bc - fc);
129 int b = fc + random.nextInt(bc - fc);
130 return new Color(r, g, b);
131 }
132
133 private static int getRandomIntColor() {
134 int[] rgb = getRandomRgb();
135 int color = 0;
136 for (int c : rgb) {
137 color = color << 8;
138 color = color | c;
139 }
140 return color;
141 }
142
143 private static int[] getRandomRgb() {
144 int[] rgb = new int[3];
145 for (int i = 0; i < 3; i++) {
146 rgb[i] = random.nextInt(255);
147 }
148 return rgb;
149 }
150
151 private static void shear(Graphics g, int w1, int h1, Color color) {
152 shearX(g, w1, h1, color);
153 shearY(g, w1, h1, color);
154 }
155
156 private static void shearX(Graphics g, int w1, int h1, Color color) {
157
158 int period = random.nextInt(2);
159
160 boolean borderGap = true;
161 int frames = 1;
162 int phase = random.nextInt(2);
163
164 for (int i = 0; i < h1; i++) {
165 double d = (double) (period >> 1)
166 * Math.sin((double) i / (double) period
167 + (6.2831853071795862D * (double) phase)
168 / (double) frames);
169 g.copyArea(0, i, w1, 1, (int) d, 0);
170 if (borderGap) {
171 g.setColor(color);
172 g.drawLine((int) d, i, 0, i);
173 g.drawLine((int) d + w1, i, w1, i);
174 }
175 }
176
177 }
178
179 private static void shearY(Graphics g, int w1, int h1, Color color) {
180
181 int period = random.nextInt(40) + 10; // 50;
182
183 boolean borderGap = true;
184 int frames = 20;
185 int phase = 7;
186 for (int i = 0; i < w1; i++) {
187 double d = (double) (period >> 1)
188 * Math.sin((double) i / (double) period
189 + (6.2831853071795862D * (double) phase)
190 / (double) frames);
191 g.copyArea(i, 0, 1, h1, 0, (int) d);
192 if (borderGap) {
193 g.setColor(color);
194 g.drawLine(i, (int) d, i, 0);
195 g.drawLine(i, (int) d + h1, i, h1);
196 }
197
198 }
199
200 }
201
202 /**
203 * 获取随机验证码及其加密图片
204 *
205 */
206 public static String VerifyCode(int w, int h, int size) throws IOException {
207 BASE64Encoder encoder = new BASE64Encoder();
208 String code = generateVerifyCode(size).toLowerCase();
209 ByteArrayOutputStream data = new ByteArrayOutputStream();
210 outputImage(w, h, data, code);
211 return encoder.encode(data.toByteArray());
212 }
213
214 public static void main(String[] args) throws Exception{
215 System.out.println(VerifyCode(100, 30, 6));
216
217 }
218}
219
220
以及java操作Redis的工具类
RedisUtils .java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 1package org.leryoo.util;
2
3import redis.clients.jedis.Jedis;
4import redis.clients.jedis.JedisPool;
5import redis.clients.jedis.JedisPoolConfig;
6
7import java.io.IOException;
8import java.util.Properties;
9
10/**
11 * 获取连接池对象
12 */
13public enum RedisUtils {
14 INSTANCE;
15 static JedisPool jedisPool = null;
16
17 static {
18 //1 创建连接池配置对象
19 JedisPoolConfig config = new JedisPoolConfig();
20 //2 进行配置-四个配置
21 config.setMaxIdle(1);//最小连接数
22 config.setMaxTotal(11);//最大连接数
23 config.setMaxWaitMillis(10 * 1000L);//最长等待时间
24 config.setTestOnBorrow(true);//测试连接时是否畅通
25 //3 通过配置对象创建连接池对象
26 Properties properties = null;
27 try {
28 properties = new Properties();
29 properties.load(RedisUtils.class.getClassLoader().getResourceAsStream("redis.properties"));
30 } catch (IOException e) {
31 e.printStackTrace();
32 }
33 String host = properties.getProperty("redis.host");
34 String port = properties.getProperty("redis.port");
35 String password = properties.getProperty("redis.password");
36 String timeout = properties.getProperty("redis.timeout");
37 System.out.println(host);
38 System.out.println(port);
39 System.out.println(password);
40 System.out.println(timeout);
41 jedisPool = new JedisPool(config, host, Integer.valueOf(port),Integer.valueOf(timeout), password);
42 }
43
44 //获取连接
45 public Jedis getSource() {
46 return jedisPool.getResource();
47 }
48
49 //关闭资源
50 public void closeSource(Jedis jedis) {
51 if (jedis != null) {
52 jedis.close();
53 }
54
55 }
56 /**
57 * 设置字符值
58 *
59 * @param key
60 * @param
61 */
62 public void del(String key) {
63 Jedis jedis = getSource();
64 jedis.del(key);
65 closeSource(jedis);
66 }
67 /**
68 * 设置字符值
69 *
70 * @param key
71 * @param value
72 */
73 public void set(String key, String value) {
74 Jedis jedis = getSource();
75 jedis.set(key, value);
76 closeSource(jedis);
77 }
78
79 /**
80 * 设置
81 * @param key
82 * @param value
83 */
84 public void set(byte[] key, byte[] value) {
85 Jedis jedis = getSource();
86 jedis.set(key, value);
87 closeSource(jedis);
88 }
89
90 /**
91 *
92 * @param key
93 * @return
94 */
95 public byte[] get(byte[] key) {
96 Jedis jedis = getSource();
97 try {
98 return jedis.get(key);
99 } catch (Exception e) {
100 e.printStackTrace();
101 } finally {
102 closeSource(jedis);
103 }
104 return null;
105
106 }
107
108 /**
109 * 设置字符值
110 *
111 * @param key
112 */
113 public String get(String key) {
114 Jedis jedis = getSource();
115 try {
116 return jedis.get(key);
117 } catch (Exception e) {
118 e.printStackTrace();
119 } finally {
120 closeSource(jedis);
121 }
122
123 return null;
124
125 }
126
127 public void set(String key, String value, Integer time) {
128 Jedis jedis = getSource();
129 jedis.setex(key,time,value);
130 closeSource(jedis);
131 }
132}
133
134
注意三个地方
注意跨域问题的配置
以及swagger中添加
还有就是配置文件中
网关的配置 记得先提交
最后生成代码
测试
运行服务
界面
到这图片验证码就集成完毕了
手机验证码
执行流程
方案选择
方案1:对接三大运营商接口 如果
量少,三大运营商甩都不甩你。
方案2:三方服务
一些有短信服务商,它们去对接三大运行商,封装为自己的接口。我们对接它们就ok。它们赚取差价。
先使用三方服务,等运营后,量大了,再找三大运营商对接。
第三方服务商
阿里大于
腾讯
华为
中国网建 http://www.smschinese.cn/ 5条是免费的
需要先登录
接下来我们来写服务模块
因为这个模块是可以公用的 所以我们就把他写在 公共模块中
hrm-web-parent
首先是客户端
1
2
3
4
5
6
7
8
9
10 1@FeignClient(value = "HRM-COMMON", fallbackFactory = SmsClientFallbackFactory.class )//服务提供
2@RequestMapping("/sms")
3public interface SmsClient {
4
5 //feign如果要传递Map list等需要特殊处理
6 @PostMapping
7 AjaxResult send(@RequestParam String params);
8}
9
10
SmsClientFallbackFactory.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1@Component
2public class SmsClientFallbackFactory implements FallbackFactory<SmsClient> {
3 @Override
4 public SmsClient create(Throwable throwable) {
5 return new SmsClient() {
6 @Override
7 public AjaxResult send(String params) {
8 return null;
9 }
10 };
11 }
12}
13
14
首先定义一个常量类
两个常量
UID是刚刚注册的用户名 KEY是刚刚的密钥
Controller.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 1@RestController
2@RequestMapping("/sms")
3public class SmsController {
4
5 @Autowired
6 private ISmsService smsService;
7 //传入的参数
8 // smsMob=手机号码&smsText=验证码:8888
9 @PostMapping
10 AjaxResult send(@RequestParam String params){
11 System.out.println(params);
12 Map<String,String> paramsTmp =
13 JSONObject.parseObject(params, Map.class);
14 //封装参数
15 paramsTmp.put("Uid", SmsContants.SMS_UID);
16 paramsTmp.put("Key", SmsContants.SMS_KEY);
17 return smsService.sendSmsCode(paramsTmp);
18 }
19}
20
21
Service层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 1@Service
2public class SmsServiceImpl implements ISmsService {
3
4 //参数可变
5 @Override
6 public AjaxResult sendSmsCode(Map<String, String> params) {
7
8 PostMethod post = null;
9 try {
10
11 HttpClient client = new HttpClient();
12 post = new PostMethod("http://utf8.api.smschinese.cn");
13 post.addRequestHeader("Content-Type",
14 "application/x-www-form-urlencoded;charset=utf-8");//在头文件中设置转码
15
16 //动态参数 //map===>list====>array
17 List<NameValuePair> datas = new ArrayList<>();
18 for (String key : params.keySet()) {
19 datas.add( new NameValuePair(key, params.get(key) ));
20 }
21 NameValuePair[] data = datas.toArray(new NameValuePair[]{});
22 post.setRequestBody(data);
23
24 client.executeMethod(post);
25 Header[] headers = post.getResponseHeaders();
26 int statusCode = post.getStatusCode(); //400 404 200 500
27 String result = new String(post.getResponseBodyAsString().getBytes("utf-8"));
28 System.out.println("statusCode:"+statusCode);
29 System.out.println(result); //打印返回消息状态
30 if (statusCode==200){
31 //对各种错误码进行处理
32 return AjaxResult.me().setMessage(result);
33 }else{
34 return AjaxResult.me().setSuccess(false).setMessage(result);
35 }
36
37 }catch (Exception e){
38 e.printStackTrace();
39 }
40 finally {
41 if (post != null) {
42 post.releaseConnection();
43 }
44 }
45 return null;
46 }
47}
48
49
然后在VerifycodeServiceImpl中去调用这个服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 1@Override
2public AjaxResult sendSmsCode(Map<String, String> params) {
3 // 一 接收参数
4 //手机号
5 String mobile = params.get("mobile");
6 //图片验证码
7 String imageCode = params.get("imageCode");
8 //图片验证码的key
9 String imageCodeKey = params.get("imageCodeKey");
10 // 二 做检验
11 //2.1 图片验证 通过key从redis获取存放验证码和输入的进行对比
12 String imgCodeforReids = redisClient.get(imageCodeKey);
13 if (imgCodeforReids==null || !imageCode.equals(imgCodeforReids)){
14 return AjaxResult.me().setSuccess(false).setMessage("图片验证码不正确!");
15 }
16 //2.2 手机号的验证-判null,是否已经注册了
17 if (mobile==null){
18 return AjaxResult.me().setSuccess(false).setMessage("请输入正确的手机号码");
19 }
20 List<Sso> ssos = ssoMapper
21 .selectList(new EntityWrapper<Sso>().eq("phone", mobile));
22 if (ssos!=null && ssos.size()>0){
23 return AjaxResult.me().setSuccess(false).setMessage("你的手机号已经注册了,可以直接使用!");
24 }
25 // 三 发送短信验证码
26 return sendSmsCode(mobile);
27}
28
29private AjaxResult sendSmsCode(String mobile) {
30 String smsKey = "SMS_CODE:"+mobile;
31 // 一 先产生一个验证码
32 String smsCode = StrUtils.getComplexRandomString(4); //面条 饭
33 //二 如果原来验证码有效,替换生成哪个
34 String smsCodeForRedis= redisClient.get(smsKey); //smsCode格式 code:time
35 if (StringUtils.hasLength(smsCodeForRedis)){
36 //2如果有效,判断是否已经过了重发时间,如果没有过就报错
37 String[] split = smsCodeForRedis.split(":");
38 String timeStr = split[1];
39 long time = System.currentTimeMillis()-Long.valueOf(timeStr);
40 if (time<1000*60){
41 return AjaxResult.me().setSuccess(false).setMessage("请不要重复发送短信验证码!");
42 }
43 //如果过了,替换原来的验证码
44 smsCode = split[0];
45 }
46 //三 存储到redis
47 redisClient.addForTime(smsKey,smsCode+":"+System.currentTimeMillis(),60*5);//5分钟过期
48 //四 都要进行发送
49 System.out.println("[Leryoo]已经发送验证码"+smsCode+"到用户手机:"+mobile);
50 Map<String,String> params = new HashMap<>();
51 //smsMob=手机号码&smsText=验证码:8888
52 params.put("smsMob",mobile);
53 params.put("smsText","验证码为:"+smsCode+",请在5分钟之内使用!");
54
55 smsClient.send(JSONObject.toJSONString(params));
56 return AjaxResult.me();
57}
58
59
因为我刚刚测试 免费的次数都用完了 所以这就不测试了 你们自己测试一下 哈哈哈
到这手机验证码的模块也就写完了
完成注册
Controller层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 1//注册
2@PostMapping("/register")
3/**
4 * mobile:'13330964748',
5 password:'123456',
6 imageCode:'',
7 smsCode:''
8 ==============Map接口---不是通过feign,通过zuul转发过来外部请求
9 */
10public AjaxResult register(@RequestBody Map<String,String> params)
11{
12 return ssoService.register(params);
13}
14
15
Service.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 1 @Override
2 public AjaxResult register(Map<String, String> params) {
3 String mobile = params.get("mobile");
4 String password = params.get("password");
5 String smsCode = params.get("smsCode");
6 //1 校验
7 AjaxResult ajaxResult = validateParam(mobile,password,smsCode);
8 if (!ajaxResult.isSuccess())
9 return ajaxResult;
10 // 2 保存sso信息
11 Sso sso = new Sso();
12 sso.setPhone(mobile);
13 //获取随机验证-32位随机字符串
14 String salt = StrUtils.getComplexRandomString(32);
15 sso.setSalt(salt);
16 //使用随机验证给密码md5加密,并设置
17 //输入密码+以后做校验的时候先从数据库查询盐=md5,再和数据库查询出来进行比较
18 String md5Password = MD5.getMD5(password + salt);
19 sso.setPassword(md5Password);
20 sso.setNickName(mobile);
21 sso.setSecLevel(0);
22 sso.setBitState(7L); // 二进制位来表示 2个小时(扩展)
23 sso.setCreateTime(System.currentTimeMillis());
24 ssoMapper.insert(sso);
25 // 3 保存关联对象信息vipbase
26 VipBase vipBase = new VipBase();
27 vipBase.setCreateTime(System.currentTimeMillis());
28 vipBase.setSsoId(sso.getId());
29 vipBase.setRegChannel(1);
30 vipBase.setRegTime(System.currentTimeMillis());
31 vipBaseMapper.insert(vipBase);
32 return AjaxResult.me();
33 }
34
35
36
37 private AjaxResult validateParam(String mobile,String password,String smsCode){
38 // 手机号密码null校验
39 if (!StringUtils.hasLength(mobile) || !StringUtils.hasLength(password))
40 return AjaxResult.me().setSuccess(false).setMessage("请输入用户名或密码!");
41 // 手机号时候已经注册
42 List<Sso> ssoList = ssoMapper.selectList(new EntityWrapper<Sso>().eq("phone", mobile));
43 if (ssoList!=null&&ssoList.size()>0)
44 return AjaxResult.me().setSuccess(false).setMessage("您已经注册过了!可以直接使用!");
45 // 短信验证码校验 通过key从redis获取
46 String smsCodeStr = redisClient.get("SMS_CODE:" + mobile); // code:time
47 String smsCodeOfRedis = smsCodeStr.split(":")[0];
48 if (!smsCodeOfRedis.equals(smsCode))
49 return AjaxResult.me().setSuccess(false).setMessage("请输入正确短信验证码");
50
51 return AjaxResult.me();
52 }
53}
54
55