Skip to content

Commit 24cf005

Browse files
committed
手机号登陆
1 parent 11ea3cb commit 24cf005

File tree

9 files changed

+178
-2
lines changed

9 files changed

+178
-2
lines changed

Diff for: omind-api/omind-api-userplat/src/main/java/org/dromara/omind/userplat/api/service/RemoteOmindUserService.java

+2
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ public interface RemoteOmindUserService {
1111
Boolean updateById(OmindUserEntity userEntity);
1212

1313
OmindUserEntity getUserById(Long uid);
14+
15+
OmindUserEntity getUserByMobile(String mobile);
1416
}

Diff for: omind-modules/omind-mp/src/main/java/org/dromara/omind/mp/controller/v1/AuthV1Controller.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,7 @@ else if(TextUtils.isBlank(mpMobileLoginRequest.getVerCode())){
174174
return R.fail("无效的验证码");
175175
}
176176

177-
//todo return mpService.mobileLogin(mpMobileLoginRequest);
178-
return null;
177+
return mpService.mobileLogin(mpMobileLoginRequest);
179178
}
180179
catch (BaseException ex){
181180
log.error(ex.toString(), ex);

Diff for: omind-modules/omind-mp/src/main/java/org/dromara/omind/mp/service/MpService.java

+4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import org.dromara.common.core.domain.R;
44
import org.dromara.omind.mp.domain.request.MpInfoRequest;
55
import org.dromara.omind.mp.domain.request.MpLoginRequest;
6+
import org.dromara.omind.mp.domain.request.MpMobileLoginRequest;
67
import org.dromara.omind.mp.domain.request.MpPhoneRequest;
8+
import org.dromara.omind.mp.domain.vo.UserVo;
79

810
public interface MpService {
911

@@ -15,4 +17,6 @@ public interface MpService {
1517

1618
public R userInfo(Long uid);
1719

20+
public R<UserVo> mobileLogin(MpMobileLoginRequest mpMobileLoginRequest);
21+
1822
}

Diff for: omind-modules/omind-mp/src/main/java/org/dromara/omind/mp/service/impl/MpServiceImpl.java

+48
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@
88
import me.chanjar.weixin.common.error.WxErrorException;
99
import org.apache.dubbo.config.annotation.DubboReference;
1010
import org.apache.http.util.TextUtils;
11+
import org.dromara.common.core.constant.GlobalConstants;
1112
import org.dromara.common.core.constant.HttpStatus;
1213
import org.dromara.common.core.domain.R;
1314
import org.dromara.common.core.exception.base.BaseException;
1415
import org.dromara.common.core.utils.ServletUtils;
16+
import org.dromara.common.core.utils.TokenUtils;
17+
import org.dromara.common.json.utils.JsonUtils;
1518
import org.dromara.common.redis.utils.RedisUtils;
1619
import org.dromara.omind.api.common.utils.ip.IpUtils;
1720
import org.dromara.omind.mp.constant.XcxRedisKey;
1821
import org.dromara.omind.mp.domain.request.MpInfoRequest;
1922
import org.dromara.omind.mp.domain.request.MpLoginRequest;
23+
import org.dromara.omind.mp.domain.request.MpMobileLoginRequest;
2024
import org.dromara.omind.mp.domain.request.MpPhoneRequest;
2125
import org.dromara.omind.mp.domain.vo.UserVo;
2226
import org.dromara.omind.mp.service.MpService;
@@ -184,4 +188,48 @@ public R userInfo(Long uid) {
184188
userVo.setUserInfo(userInfo);
185189
return R.ok(userVo);
186190
}
191+
192+
@Override
193+
public R<UserVo> mobileLogin(MpMobileLoginRequest mpMobileLoginRequest) {
194+
String key = GlobalConstants.CAPTCHA_CODE_KEY + mpMobileLoginRequest.getMobile();
195+
if(!RedisUtils.hasKey(key)){
196+
return R.fail("无效的验证码");
197+
}
198+
String verCode = RedisUtils.getCacheObject(key).toString();
199+
if(TextUtils.isBlank(verCode)){
200+
return R.fail("无效的验证码");
201+
}
202+
else if(!verCode.equals(mpMobileLoginRequest.getVerCode())){
203+
return R.fail("无效的验证码");
204+
}
205+
final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
206+
//正确 开始登录/注册
207+
OmindUserEntity omindUserEntity = userService.getUserByMobile(mpMobileLoginRequest.getMobile());
208+
if(omindUserEntity == null){
209+
//注册用户
210+
omindUserEntity = new OmindUserEntity();
211+
omindUserEntity.setMobile(mpMobileLoginRequest.getMobile());
212+
omindUserEntity.setLastVisitIp(ip);
213+
omindUserEntity.setLastVisitTime(new Date());
214+
if(!userService.addUser(omindUserEntity)){
215+
return R.fail("用户注册失败");
216+
}
217+
//补充默认值
218+
omindUserEntity = userService.getUserByMobile(mpMobileLoginRequest.getMobile());
219+
}
220+
else{
221+
omindUserEntity.setLastVisitIp(ip);
222+
omindUserEntity.setLastVisitTime(new Date());
223+
userService.updateById(omindUserEntity);
224+
}
225+
if(omindUserEntity.getDisableFlag() == 1){
226+
throw new BaseException("账号被禁用,请联系管理员");
227+
}
228+
String token = TokenUtils.generateToken(JsonUtils.toJsonString(omindUserEntity));
229+
RedisUtils.setCacheObject(XcxRedisKey.USER_TOKEN + token, omindUserEntity.getUid(), Duration.ofDays(1));
230+
UserVo userVo = new UserVo();
231+
userVo.setToken(token);
232+
userVo.setUserInfo(omindUserEntity);
233+
return R.ok(userVo);
234+
}
187235
}

Diff for: omind-modules/omind-userplat/src/main/java/org/dromara/omind/userplat/constant/PlatRedisKey.java

+5
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,9 @@ public interface PlatRedisKey {
115115
*/
116116
String USER_CAR_INFO = VER + "user:car:info:";
117117

118+
/**
119+
* 根据手机号获取用户信息
120+
*/
121+
String USER_INFO_BY_MOBILE = VER + "user:info4mobile";
122+
118123
}

Diff for: omind-modules/omind-userplat/src/main/java/org/dromara/omind/userplat/dubbo/RemoteOmindUserServiceImpl.java

+5
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,10 @@ public OmindUserEntity getUserById(Long uid) {
3636
return omindUserService.getUserById(uid);
3737
}
3838

39+
@Override
40+
public OmindUserEntity getUserByMobile(String mobile) {
41+
return omindUserService.getUserByMobile(mobile);
42+
}
43+
3944

4045
}

Diff for: omind-modules/omind-userplat/src/main/java/org/dromara/omind/userplat/service/OmindUserService.java

+2
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ public interface OmindUserService {
2828
TableDataInfo<OmindUserEntity> selectUserList(OmindUserListDto omindUserListDto, PageQuery pageQuery);
2929

3030
int disableUser(OmindUserOptDto omindUserOptDto) throws BaseException;
31+
32+
OmindUserEntity getUserByMobile(String mobile);
3133
}

Diff for: omind-modules/omind-userplat/src/main/java/org/dromara/omind/userplat/service/impl/OmindUserServiceImpl.java

+29
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,33 @@ public int disableUser(OmindUserOptDto omindUserOptDto) throws BaseException {
198198

199199
return 0;
200200
}
201+
202+
@Override
203+
public OmindUserEntity getUserByMobile(String mobile) {
204+
if(TextUtils.isBlank(mobile)){
205+
return null;
206+
}
207+
String key = PlatRedisKey.USER_INFO_BY_MOBILE + mobile;
208+
OmindUserEntity odUserEntity = null;
209+
if (RedisUtils.hasKey(key)) {
210+
odUserEntity = RedisUtils.getCacheObject(key);
211+
if (odUserEntity != null) {
212+
RedisUtils.expire(key, PlatRedisKey.TOKEN_VALID_DURANT);
213+
RedisUtils.setCacheObject(key, odUserEntity);
214+
return odUserEntity;
215+
} else {
216+
RedisUtils.deleteObject(key);
217+
}
218+
}
219+
//还是通过查uid 再统一查询构建缓存比较合适,以免多次调用
220+
LambdaQueryWrapper<OmindUserEntity> lambdaQuery = Wrappers.lambdaQuery();
221+
lambdaQuery.eq(OmindUserEntity::getMobile, mobile);
222+
List<OmindUserEntity> list = iService.list(lambdaQuery);
223+
if (list == null || list.isEmpty()) {
224+
return null;
225+
}
226+
odUserEntity = list.get(0);
227+
RedisUtils.setCacheObject(key, list.get(0));
228+
return odUserEntity;
229+
}
201230
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package org.dromara.common.core.utils;
2+
3+
import javax.crypto.Mac;
4+
import javax.crypto.spec.SecretKeySpec;
5+
import java.security.InvalidKeyException;
6+
import java.security.NoSuchAlgorithmException;
7+
import java.time.LocalDateTime;
8+
import java.time.ZoneOffset;
9+
import java.util.Base64;
10+
11+
/**
12+
* @author : flainsky
13+
* @version : V0.0
14+
* @data : 2025/3/8 16:14
15+
* @company : ucode
16+
* @email : [email protected]
17+
* @title :
18+
* @Description :
19+
*/
20+
public class TokenUtils {
21+
22+
private static final String HMAC_ALGORITHM = "HmacSHA256";
23+
private static final String SECRET_KEY = "9s1ga3yx9b85ve1l";
24+
25+
// 生成 Token
26+
public static String generateToken(String payload) {
27+
try {
28+
// 创建 HMAC-SHA256 密钥
29+
SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), HMAC_ALGORITHM);
30+
Mac mac = Mac.getInstance(HMAC_ALGORITHM);
31+
mac.init(secretKeySpec);
32+
33+
// 计算签名
34+
byte[] signatureBytes = mac.doFinal(payload.getBytes());
35+
36+
// 使用 Base64 编码签名
37+
String signature = Base64.getEncoder().encodeToString(signatureBytes);
38+
39+
// 返回 Token,格式为 payload.signature
40+
return Base64.getEncoder().encodeToString(payload.getBytes()) + "." + signature;
41+
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
42+
e.printStackTrace();
43+
return null;
44+
}
45+
}
46+
47+
// 校验 Token
48+
public static boolean verifyToken(String token) {
49+
try {
50+
// 提取载荷和签名
51+
String[] parts = token.split("\\.");
52+
String payload = parts[0];
53+
String receivedSignature = parts[1];
54+
55+
// 创建 HMAC-SHA256 密钥
56+
SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), HMAC_ALGORITHM);
57+
Mac mac = Mac.getInstance(HMAC_ALGORITHM);
58+
mac.init(secretKeySpec);
59+
60+
// 计算签名
61+
byte[] calculatedSignatureBytes = mac.doFinal(payload.getBytes());
62+
String calculatedSignature = Base64.getEncoder().encodeToString(calculatedSignatureBytes);
63+
64+
// 验证签名是否一致
65+
if(!receivedSignature.equals(calculatedSignature)){
66+
return false;
67+
}
68+
// 提取过期时间
69+
String expirationTime = new String(Base64.getDecoder().decode(payload)).split("\"expires_at\":\"")[1].split("\"")[0];
70+
71+
// 检查有效期
72+
LocalDateTime expiresAt = LocalDateTime.parse(expirationTime);
73+
LocalDateTime currentTime = LocalDateTime.now(ZoneOffset.UTC);
74+
return currentTime.isBefore(expiresAt);
75+
76+
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
77+
e.printStackTrace();
78+
return false;
79+
}
80+
}
81+
82+
}

0 commit comments

Comments
 (0)