Springcloud微服务项目——人力资源管理(HRM)Day10 用户管理(图片验证码 手机验证码)

释放双眼,带上耳机,听听看~!

用户管理

老规矩 先新建用户模块

这里没有客户端模块 是因为用户模块是一个单独的模块 不用服务之间的调用
导入总的依赖


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

给TA打赏
共{{data.count}}人
人已打赏
安全经验

海外中文博客与Adsense

2021-10-11 16:36:11

安全经验

安全咨询服务

2022-1-12 14:11:49

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索