浏览代码

短信邮箱发送配置
添加验证码 token

wangmh 8 年之前
父节点
当前提交
5b5e02c244

+ 41 - 0
pom.xml

@@ -25,6 +25,11 @@
         <fastjson.version>1.2.15</fastjson.version>
         <druid.version>1.0.24</druid.version>
         <mysql.jdbc.version>5.1.41</mysql.jdbc.version>
+        <message.version>0.0.1</message.version>
+        <dubbo.version>2.8.4</dubbo.version>
+        <zookeeper.version>3.4.6</zookeeper.version>
+        <zkclient.version>0.1</zkclient.version>
+        <dfs.version>0.0.2</dfs.version>
     </properties>
 
     <dependencyManagement>
@@ -49,6 +54,42 @@
                 <artifactId>spring-context</artifactId>
                 <version>${spring.version}</version>
             </dependency>
+
+            <!-- message center -->
+            <dependency>
+                <groupId>com.uas.message</groupId>
+                <artifactId>message-mail-api</artifactId>
+                <version>${message.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.uas.message</groupId>
+                <artifactId>message-sms-api</artifactId>
+                <version>${message.version}</version>
+            </dependency>
+
+            <!-- dubbo -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>dubbo</artifactId>
+                <version>${dubbo.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.zookeeper</groupId>
+                <artifactId>zookeeper</artifactId>
+                <version>${zookeeper.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.github.sgroschupf</groupId>
+                <artifactId>zkclient</artifactId>
+                <version>${zkclient.version}</version>
+            </dependency>
+
+            <!-- dfs service on dubbo -->
+            <dependency>
+                <groupId>com.uas.dfs</groupId>
+                <artifactId>dfs-api</artifactId>
+                <version>${dfs.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

+ 48 - 0
sso-server/pom.xml

@@ -38,6 +38,17 @@
 			<groupId>org.springframework</groupId>
 			<artifactId>spring-tx</artifactId>
 		</dependency>
+
+		<!-- Redis session -->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-redis</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.session</groupId>
+			<artifactId>spring-session</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>mysql</groupId>
 			<artifactId>mysql-connector-java</artifactId>
@@ -50,6 +61,15 @@
 			<groupId>com.alibaba</groupId>
 			<artifactId>fastjson</artifactId>
 		</dependency>
+
+		<dependency>
+			<groupId>com.uas.message</groupId>
+			<artifactId>message-mail-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.uas.message</groupId>
+			<artifactId>message-sms-api</artifactId>
+		</dependency>
 		<dependency>
 			<groupId>com.uas.account</groupId>
 			<artifactId>sso-core</artifactId>
@@ -60,6 +80,34 @@
 			<artifactId>sso-common</artifactId>
 			<version>0.0.1-SNAPSHOT</version>
 		</dependency>
+
+		<!-- dubbo -->
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>dubbo</artifactId>
+			<exclusions>
+				<exclusion>
+					<groupId>javax.servlet</groupId>
+					<artifactId>javax.servlet-api</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.apache.httpcomponents</groupId>
+					<artifactId>httpcore</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.zookeeper</groupId>
+			<artifactId>zookeeper</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.github.sgroschupf</groupId>
+			<artifactId>zkclient</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.uas.dfs</groupId>
+			<artifactId>dfs-api</artifactId>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 2 - 0
sso-server/src/main/java/com/uas/sso/Application.java

@@ -5,6 +5,7 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.context.event.ApplicationPreparedEvent;
 import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.ImportResource;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 
@@ -23,6 +24,7 @@ import java.io.PrintStream;
 @EnableTransactionManagement
 @SpringBootApplication
 @EnableWebMvc
+@ImportResource("classpath:spring/*.xml")
 public class Application {
     public static void main(String[] args) throws FileNotFoundException {
         File logFile = new File("logs/log.log");

+ 15 - 0
sso-server/src/main/java/com/uas/sso/RedisSessionConfig.java

@@ -0,0 +1,15 @@
+package com.uas.sso;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+
+/**
+ *
+ * @author wangmh
+ * @date 2018/1/3
+ */
+@Configuration
+@EnableRedisHttpSession
+public class RedisSessionConfig {
+
+}

+ 89 - 1
sso-server/src/main/java/com/uas/sso/controller/PersonalRegisterController.java

@@ -1,11 +1,17 @@
 package com.uas.sso.controller;
 
+import com.uas.message.sms.service.SmsService;
 import com.uas.sso.core.Const;
 import com.uas.sso.core.Type;
 import com.uas.sso.core.PasswordStrength;
+import com.uas.sso.entity.Setting;
+import com.uas.sso.entity.Token;
 import com.uas.sso.entity.User;
 import com.uas.sso.logging.RegisterBufferedLogger;
+import com.uas.sso.service.SettingService;
+import com.uas.sso.service.TokenService;
 import com.uas.sso.service.UserService;
+import com.uas.sso.util.StringUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.ModelMap;
@@ -27,11 +33,29 @@ public class PersonalRegisterController extends BaseController {
     @Autowired
     private UserService userService;
 
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private SettingService settingService;
+
+    @Autowired
+    private SmsService smsService;
+
     private RegisterBufferedLogger registerLogger = new RegisterBufferedLogger();
 
+    /**
+     * 注册个人信息
+     *
+     * @param user 用户信息(需要会员名,手机号,手机号所属区域,密码)
+     * @param appId 注册应用标志
+     * @param code 验证码
+     * @param token 验证码tokenId
+     * @return 成功:success(),失败:error("错误码", "错误信息")
+     */
     @RequestMapping(value = "/register", method = RequestMethod.POST)
     @ResponseBody
-    public ModelMap register(User user, String appId) {
+    public ModelMap register(User user, String appId, String code, String token) {
         // 获取参数
         String vipName = user.getVipName();
         String mobile = user.getMobile();
@@ -49,6 +73,13 @@ public class PersonalRegisterController extends BaseController {
             return error("400", "手机号不能为空");
         }
 
+        // 校验验证码
+        ModelMap checkResult = checkCode(code, token);
+        if (checkResult.get(Const.SUCCESS) == null) {
+            // 校验不成功,返回校验的错误信息
+            return checkResult;
+        }
+
         // 校验手机号
         if (Const.CONTINENT.equals(mobileArea)) {
             if (!mobile.matches(Const.REGEXP_MOBILE_CONTINENT)) {
@@ -74,4 +105,61 @@ public class PersonalRegisterController extends BaseController {
 
         return success();
     }
+
+    /**
+     * 获取验证码
+     *
+     * @param tel 手机号
+     * @return success(tokenId)
+     */
+    @RequestMapping(value = "/checkCode", method = RequestMethod.GET)
+    @ResponseBody
+    public ModelMap getCode(String tel) {
+        String code = StringUtil.getRandomNumber(6);
+        Token token = new Token(code, 10*60);
+        tokenService.save(token);
+        ModelMap data = new ModelMap();
+        data.put("checkcode", code);
+        request.getSession().setAttribute("token", token.getId());
+        // 手机短信
+        try {
+            if (!StringUtils.isEmpty(tel)) {
+                Setting smsTplId = settingService.findOne("templateForSendSmsWhenRegister");
+                if (!StringUtils.isEmpty(smsTplId)) {
+                    smsService.send(smsTplId.getValue(), tel, new Object[]{code});
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return new ModelMap("token", token.getId());
+    }
+
+    /**
+     * 校验验证码
+     *
+     * @param code 验证码
+     * @param token 验证码tokenId
+     * @return 验证成功:success(),验证失败:error("错误信息")
+     */
+    @RequestMapping(value = "/checkCode", method = RequestMethod.POST)
+    @ResponseBody
+    public ModelMap checkCode(String code, String token) {
+        // 校验参数
+        if (StringUtils.isEmpty(token) || StringUtils.isEmpty(token)) {
+            return error("参数错误");
+        }
+        Token existToken = tokenService.findOne(token);
+        if (existToken == null || existToken.isExpired()) {
+            return error("验证码已经失效,请重新获取");
+        }
+
+        // 校验验证码
+        String existCode = existToken.getBind().toString();
+        if (!code.equals(existCode)) {
+            return error("验证码错误");
+        }
+
+        return success();
+    }
 }

+ 8 - 0
sso-server/src/main/java/com/uas/sso/core/Const.java

@@ -42,4 +42,12 @@ public class Const {
      * 盐值
      */
     public static final String ENCRY_PARAM_SALT = "$salt";
+
+    public static final int NO = 0;
+
+    public static final int YES = 1;
+
+    public static final String SUCCESS = "success";
+
+    public static final String ERROR = "error";
 }

+ 12 - 0
sso-server/src/main/java/com/uas/sso/dao/SettingDao.java

@@ -0,0 +1,12 @@
+package com.uas.sso.dao;
+
+import com.uas.sso.entity.Setting;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+/**
+ * @author wangmh
+ */
+public interface SettingDao extends JpaRepository<Setting, String>, JpaSpecificationExecutor<Setting> {
+
+}

+ 3 - 0
sso-server/src/main/java/com/uas/sso/entity/RegisterLog.java

@@ -54,6 +54,9 @@ public class RegisterLog extends BaseLog {
     @Column(name = "fromApp")
     private String fromAppUid;
 
+    public RegisterLog() {
+    }
+
     public RegisterLog(String type, int step, String msg, Object msgDetail, String fromAppUid) {
         this.type = type;
         this.step = step;

+ 84 - 0
sso-server/src/main/java/com/uas/sso/entity/Setting.java

@@ -0,0 +1,84 @@
+package com.uas.sso.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.io.Serializable;
+
+/**
+ * 短信邮箱设置
+ * @author wangmh
+ */
+@Entity
+@Table(name = "sso$setting")
+public class Setting implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 描述
+	 */
+	@Column(name = "description")
+	private String description;
+
+	/**
+	 * 唯一标志
+	 */
+	@Id
+	@Column(name = "_key")
+	private String key;
+
+	/**
+	 * 模板id
+	 */
+	@Column(name = "value")
+	private String value;
+
+	/**
+	 * 是否允许删除
+	 */
+	@Column(name = "deleteable")
+	private Integer deleteable;
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	/**
+	 * 是否允许删除
+	 * 
+	 * @return
+	 */
+	public Integer getDeleteable() {
+		return deleteable;
+	}
+
+	public void setDeleteable(Integer deleteable) {
+		this.deleteable = deleteable;
+	}
+
+}

+ 86 - 0
sso-server/src/main/java/com/uas/sso/entity/Token.java

@@ -0,0 +1,86 @@
+package com.uas.sso.entity;
+
+import com.uas.sso.util.StringUtil;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class Token implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private String id;
+
+	private Object bind;
+
+	private Date time;
+
+	private int expires_in;
+
+	/**
+	 * 60秒过期
+	 */
+	public final static int default_expires_in = 60;
+
+	public Token() {
+	}
+
+	public Token(Object bindObject) {
+		this(bindObject, default_expires_in);
+	}
+
+	public Token(Object bindObject, int expires_in) {
+		this(StringUtil.uuid(), bindObject, expires_in);
+	}
+
+	public Token(String id, Object bindObject, int expires_in) {
+		this.id = id;
+		this.bind = bindObject;
+		this.time = new Date();
+		this.expires_in = expires_in;
+	}
+
+	public Date getTime() {
+		return time;
+	}
+
+	public void setTime(Date time) {
+		this.time = time;
+	}
+
+	public int getExpires_in() {
+		return expires_in;
+	}
+
+	public void setExpires_in(int expires_in) {
+		this.expires_in = expires_in;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public Object getBind() {
+		return bind;
+	}
+
+	public void setBind(Object bind) {
+		this.bind = bind;
+	}
+
+	/**
+	 * 是否过期
+	 * 
+	 * @return
+	 */
+	public boolean isExpired() {
+		return System.currentTimeMillis() - this.time.getTime() > expires_in * 1000;
+	}
+}

+ 3 - 0
sso-server/src/main/java/com/uas/sso/entity/UserLog.java

@@ -68,6 +68,9 @@ public class UserLog extends BaseLog implements Serializable {
     @Column(name = "otherMsg")
     private String otherMsg;
 
+    public UserLog() {
+    }
+
     public UserLog(User user, String level, String type) {
         this(user, level, type, null);
     }

+ 19 - 0
sso-server/src/main/java/com/uas/sso/service/SettingService.java

@@ -0,0 +1,19 @@
+package com.uas.sso.service;
+
+import com.uas.sso.entity.Setting;
+
+import java.util.List;
+
+public interface SettingService {
+
+	Setting save(Setting setting);
+
+	void save(List<Setting> settings);
+
+	Setting findOne(String key);
+
+	void delete(String key);
+
+	List<Setting> findAll();
+
+}

+ 32 - 0
sso-server/src/main/java/com/uas/sso/service/TokenService.java

@@ -0,0 +1,32 @@
+package com.uas.sso.service;
+
+import com.uas.sso.entity.Token;
+import org.springframework.stereotype.Service;
+
+/**
+ * token service
+ *
+ * @author wangmh
+ * @date 2018/1/3
+ */
+public interface TokenService {
+
+    /**
+     * 保存token
+     * @param token
+     */
+    void save(Token token);
+
+    /**
+     * 根据token id 找到token
+     * @param tokenId tokenId
+     * @return token
+     */
+    Token findOne(String tokenId);
+
+    /**
+     * 删除token
+     * @param tokenId tokenId
+     */
+    void delete(String tokenId);
+}

+ 56 - 0
sso-server/src/main/java/com/uas/sso/service/impl/SettingServiceImpl.java

@@ -0,0 +1,56 @@
+package com.uas.sso.service.impl;
+
+import com.uas.sso.core.Const;
+import com.uas.sso.dao.SettingDao;
+import com.uas.sso.entity.Setting;
+import com.uas.sso.exception.VisibleError;
+import com.uas.sso.service.SettingService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class SettingServiceImpl implements SettingService {
+
+	@Autowired
+	private SettingDao settingDao;
+
+	@Override
+	@CacheEvict(value = "setting", key = "#setting.key")
+	public Setting save(Setting setting) {
+		return settingDao.save(setting);
+	}
+
+	@Override
+	@CacheEvict(value = "setting", allEntries = true)
+	public void save(List<Setting> settings) {
+		settingDao.save(settings);
+	}
+
+	@Override
+	@Cacheable(value = "setting")
+	public Setting findOne(String key) {
+		return settingDao.findOne(key);
+	}
+
+	@Override
+	@CacheEvict(value = "setting")
+	public void delete(String key) {
+		Setting setting = findOne(key);
+		if (setting != null) {
+			if (Const.NO == setting.getDeleteable()) {
+				throw new VisibleError("该设置不允许删除");
+			}
+			settingDao.delete(key);
+		}
+	}
+
+	@Override
+	public List<Setting> findAll() {
+		return settingDao.findAll();
+	}
+
+}

+ 38 - 0
sso-server/src/main/java/com/uas/sso/service/impl/TokenServiceImpl.java

@@ -0,0 +1,38 @@
+package com.uas.sso.service.impl;
+
+import com.uas.sso.entity.Token;
+import com.uas.sso.service.TokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * token service实现
+ *
+ * @author wangmh
+ * @date 2018/1/3
+ */
+@Service
+public class TokenServiceImpl implements TokenService {
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    @Override
+    public void save(Token token) {
+        redisTemplate.opsForValue().set(token.getId(), token, token.getExpires_in(), TimeUnit.SECONDS);
+    }
+
+    @Override
+    public Token findOne(String tokenId) {
+        Token token = (Token) redisTemplate.opsForValue().get(tokenId);
+        return token;
+    }
+
+    @Override
+    public void delete(String tokenId) {
+        redisTemplate.delete(tokenId);
+    }
+}

+ 34 - 0
sso-server/src/main/java/com/uas/sso/util/StringUtil.java

@@ -0,0 +1,34 @@
+package com.uas.sso.util;
+
+import java.util.Random;
+import java.util.UUID;
+
+public class StringUtil {
+
+	/**
+	 * 产生唯一字符串
+	 * 
+	 * @return
+	 */
+	public static String uuid() {
+		return UUID.randomUUID().toString().replaceAll("\\-", "");
+	}
+
+	public static String substr(String str, int begin, int end) {
+		return str.substring(begin, Math.min(str.length(), end));
+	}
+
+	/**
+	 * 随机数字
+	 * 
+	 * @param len
+	 *            数字长度
+	 * @return
+	 */
+	public static String getRandomNumber(int len) {
+		int max = (int) Math.pow(10, len) - 1;
+		int min = (int) Math.pow(10, len - 1);
+		return String.valueOf(new Random().nextInt(max) % (max - min + 1) + min);
+	}
+
+}

+ 6 - 1
sso-server/src/main/resources/config/application-dev.properties

@@ -16,4 +16,9 @@ datasource.poolPreparedStatements=true
 datasource.timeBetweenLogStatsMillis=60000
 datasource.maxPoolPreparedStatementPerConnectionSize=20
 datasource.filters=stat,slf4j
-datasource.connectionProperties=druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000
+datasource.connectionProperties=druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000
+
+spring.redis.host=10.10.100.200
+spring.redis.port=6379
+
+zk.url=zookeeper://10.10.100.11:2181

+ 19 - 0
sso-server/src/main/resources/spring/dubbo.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
+
+    <dubbo:application name="b2b_consumer" />
+
+    <dubbo:registry address="${zk.url}" check="false" />
+
+    <!-- 分布式文件服务 -->
+    <dubbo:reference id="fileClient" interface="com.uas.dfs.service.FileClient" timeout="100000"/>
+
+    <!-- 邮件服务 -->
+    <dubbo:reference id="mailService" interface="com.uas.message.mail.service.MailService" timeout="30000" />
+
+    <!-- 短信服务 -->
+    <dubbo:reference id="smsService" interface="com.uas.message.sms.service.SmsService" timeout="30000" />
+</beans>