1
0
mirror of https://gitee.com/incloudcode/yexuejc-springboot.git synced 2025-09-28 10:53:21 +08:00

Merge remote-tracking branch 'origin/1.x' into 1.x

# Conflicts:
#	yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/security/UserServiceImpl.java
This commit is contained in:
2018-12-03 10:51:39 +08:00
17 changed files with 245 additions and 82 deletions

View File

@@ -9,7 +9,7 @@
<parent>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>1.1.9</version>
<version>1.2.0</version>
<!-- 本地打包:使用相对关联路径 -->
<!--<relativePath>../../yexuejc</relativePath>-->
</parent>

View File

@@ -13,11 +13,12 @@ import com.yexuejc.springboot.base.constant.LogTypeConsts;
import com.yexuejc.springboot.base.exception.ThirdPartyAuthorizationException;
import com.yexuejc.springboot.base.mapper.ConsumerMapper;
import com.yexuejc.springboot.base.security.domain.Consumer;
import com.yexuejc.springboot.base.security.inte.User;
import com.yexuejc.springboot.base.security.inte.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@@ -44,28 +45,42 @@ public class UserServiceImpl implements UserService {
/**
* 根据用户名到数据库查询用户
* <p>
* 账号未找到抛出UsernameNotFoundException异常=>会走第三方登录流程
* </p>
*
* @param username 登录账号
* @return
*/
@Override
public User getConsumerByUserName(String username) {
public Object getConsumerByUserName(String username) {
if (StrUtil.isEmpty(username)) {
throw new UsernameNotFoundException(username);
throw new UsernameNotFoundException("username为空一般是第三方登录来的直接抛出UsernameNotFoundException就是");
}
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("mobile", username);
Consumer consumer = consumerMapper.selectOne(queryWrapper);
if (null == consumer) {
throw new UsernameNotFoundException(username);
/**
* 1.抛出UsernameNotFoundException这个异常如果是第三方登录会走 {@link #checkOpenId(ConsumerToken)}
* 2.抛出其他Exception可以自己到{@link MySecurityConfig#loginHodler(ConsumerAuthenticationProcessingFilter)}
* 里面的filter.setAuthenticationFailureHandler()中做特殊处理
*/
throw new UsernameNotFoundException("没有该账号相关信息");
}
//h2不支持json人为处理角色
ArrayList roles = new ArrayList<>();
roles.add("ROLE_CONSUMER");
consumer.setRoles(roles);
return consumer;
//1.consumer为User的实现类
// return consumer;
//2. 自己创建ConsumerUser直接返回
List<GrantedAuthority> authorities = new ArrayList<>();
for (String role : consumer.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role));
}
ConsumerUser consumerUser = new ConsumerUser(consumer.getMobile(), consumer.getPwd(),
consumer.getEnable(), consumer.getNonExpire(), true, consumer.getNonLock(),
authorities, consumer.getConsumerId(), null, System.currentTimeMillis());
return consumerUser;
}
/**
@@ -98,15 +113,14 @@ public class UserServiceImpl implements UserService {
}
/**
* 第三方登录
* 校验openid 根据自己业务做判断
* <br/>
* 返回:封装登录用户信息到 apiVO.setObject1(User.class) 自己封装登录用户信息
*
* @param consumerToken 登录信息
* @return
*/
@Override
public ApiVO checkOpenId(ConsumerToken consumerToken) {
public Object checkOpenId(ConsumerToken consumerToken) {
ApiVO apiVO = new ApiVO(ApiVO.STATUS.F, "没有找到用户信息");
switch (consumerToken.getLogtype()) {
case LogTypeConsts.QQ:
@@ -121,9 +135,89 @@ public class UserServiceImpl implements UserService {
default:
break;
}
return apiVO;
if (apiVO.isFail()) {
/**
* 未查到:
* 1.返回null会走数据库没有这个openid[第三方账号]信息)新增流程 {@link #addConsumer(ConsumerToken)}
* 2.也可以自己创建一个带有特殊标识的ConsumerUser然后在 {@link MySecurityConfig#loginHodler(ConsumerAuthenticationProcessingFilter)}
* 里面的filter.setAuthenticationSuccessHandler()中做特殊处理 ps:假装登录成功 :)
*/
return null;
}
//h2不支持json人为处理角色
ArrayList roles = new ArrayList<>();
roles.add("ROLE_CONSUMER");
apiVO.getObject1(Consumer.class).setRoles(roles);
//根据openid到数据库查到consumer返回
return apiVO.getObject1(Consumer.class);
}
/**
* {@link #checkOpenId(ConsumerToken)} 返回null会走该方法
* 没有账号时处理自己的业务,此处必须返回 构造出的登录用户,否则会抛出{@link ThirdPartyAuthorizationException 第三方授权异常}
* <br/>
*
* @param consumerToken 登录信息
* @return
*/
@Override
public Object addConsumer(ConsumerToken consumerToken) {
Consumer consumer = new Consumer();
consumer.setConsumerId(StrUtil.genUUID());
consumer.setMobile(StrUtil.isNotEmpty(consumerToken.getUsername()) ? consumerToken.getUsername() : consumerToken.getOpenid());
consumer.setPwd(StrUtil.toMD5("123456"));
consumer.setEnable(true);
consumer.setNonExpire(true);
consumer.setNonLock(true);
List<String> roles = new ArrayList<>();
roles.add("ROLE_CONSUMER");
consumer.setRoles(roles);
switch (consumerToken.getLogtype()) {
case LogTypeConsts.SMS:
ApiVO apiVO = checkSmsCode2Redis(BizConsts.CONSUMER_LOGIN_SMS, consumerToken.getUsername(),
consumerToken.getSmscode());
if (apiVO.isFail()) {
throw new ThirdPartyAuthorizationException("短信验证码错误");
}
consumer.setNickname(consumerToken.getUsername());
consumer.setHead("/head/def.png");
consumer.setRegType(DictRegTypeConsts.DICT_MOBILE);
break;
case LogTypeConsts.QQ:
consumer.setQqId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_QQ);
break;
case LogTypeConsts.WECHAT:
consumer.setWechatId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_WECHAT);
break;
case LogTypeConsts.WEIBO:
consumer.setWeiboId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_WEIBO);
break;
default:
throw new ThirdPartyAuthorizationException("暂不支持该第三方授权");
}
Integer result = consumerMapper.insert(consumer);
if (result < 1) {
/**
* 会抛出{@link ThirdPartyAuthorizationException 第三方授权异常}
*/
return null;
}
return consumer;
}
/**
* 第三方登录 QQ登录
*
@@ -183,69 +277,6 @@ public class UserServiceImpl implements UserService {
}
/**
* 没有账号时处理自己的业务,此次必须返回 构造出的登录用户,否则会抛出{@link ThirdPartyAuthorizationException 第三方授权异常}
* <br/>
* 返回:封装登录用户信息到 apiVO.setObject1(User.class) 自己封装登录用户信息
*
* @param consumerToken 登录信息
* @return
*/
@Override
public ApiVO addConsumer(ConsumerToken consumerToken) {
Consumer consumer = new Consumer();
consumer.setConsumerId(StrUtil.genUUID());
consumer.setMobile(StrUtil.isNotEmpty(consumerToken.getUsername()) ? consumerToken.getUsername() : consumerToken.getOpenid());
consumer.setPwd(StrUtil.toMD5("123456"));
consumer.setEnable(true);
consumer.setNonExpire(true);
consumer.setNonLock(true);
List<String> roles = new ArrayList<>();
roles.add("ROLE_CONSUMER");
consumer.setRoles(roles);
switch (consumerToken.getLogtype()) {
case LogTypeConsts.SMS:
ApiVO apiVO = checkSmsCode2Redis(BizConsts.CONSUMER_LOGIN_SMS, consumerToken.getUsername(),
consumerToken.getSmscode());
if (apiVO.isFail()) {
return apiVO;
}
consumer.setNickname(consumerToken.getUsername());
consumer.setHead("/head/def.png");
consumer.setRegType(DictRegTypeConsts.DICT_MOBILE);
break;
case LogTypeConsts.QQ:
consumer.setQqId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_QQ);
break;
case LogTypeConsts.WECHAT:
consumer.setWechatId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_WECHAT);
break;
case LogTypeConsts.WEIBO:
consumer.setWeiboId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_WEIBO);
break;
default:
return new ApiVO(ApiVO.STATUS.F, "暂不支持的登录方式");
}
Integer result = consumerMapper.insert(consumer);
if (result < 1) {
return new ApiVO(ApiVO.STATUS.F, RespsConsts.CODE_FAIL, "登录失败");
}
return new ApiVO(ApiVO.STATUS.S).setObject1(consumer);
}
public Consumer getConsumerByQQOpenid(String openid) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("qq_id", openid);

View File

@@ -1,7 +1,23 @@
package com.yexuejc.springboot.base.web;
import com.yexuejc.base.http.Resps;
import com.yexuejc.base.pojo.ApiVO;
import com.yexuejc.base.util.RegexUtil;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
import com.yexuejc.springboot.base.constant.BizConsts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* <pre>
* Security 登录注册相关controller
@@ -19,5 +35,49 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
public class SecurityCtrl {
@Autowired
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE1)
RedisTemplate<Object, Object> redisTemplate;
/**
* 登录发送短信
*
* @param mobile
* @return
*/
@RequestMapping(value = "/login/{mobile}", method = RequestMethod.POST)
public Resps login(@PathVariable String mobile) {
if (!RegexUtil.regex(mobile, RegexUtil.REGEX_MOBILE)) {
return Resps.fail("手机号不正确");
}
ApiVO apiVO = sendSmsCode(BizConsts.CONSUMER_LOGIN_SMS, mobile);
if (apiVO.isFail()) {
return Resps.fail(apiVO.getMsg());
}
return Resps.success(apiVO.getMsg());
}
private ApiVO sendSmsCode(String smsType, String mobile) {
String smsId = StrUtil.genUUID(30);
String code = StrUtil.genNum().substring(2, 8);
//自己接入短信发送
boolean result = true;
if (result) {
//成功
//存reids
Map<String, Object> map = new HashMap<>();
map.put("smsId", smsId);
map.put("code", code);
map.put("trade_id", "短信返回id");
map.put("validatedNums", 0);
redisTemplate.afterPropertiesSet();
redisTemplate.opsForHash().putAll(smsType + "." + mobile, map);
// 过期时间5分钟
redisTemplate.expire(smsType + "." + mobile, 5 * 60, TimeUnit.SECONDS);
return new ApiVO(ApiVO.STATUS.S, "短信发送成功");
} else {
return new ApiVO(ApiVO.STATUS.F, "短信发送失败");
}
}
}