Commit 92552f1ba4933c4b2049f8df99fb30ac01328d5a
1 parent
1e6b8a96
分布式环境激活码问题解决
Signed-off-by: TanYibin <5491541@qq.com>
Showing
7 changed files
with
87 additions
and
84 deletions
ant-design-vue-jeecg/src/views/user/modules/SystemActivationModal.vue
... | ... | @@ -2,12 +2,7 @@ |
2 | 2 | <div class="main"> |
3 | 3 | <a-form-model class="user-layout-login" @keyup.enter.native="handleSubmit" :model="model" :rules="validatorRules"> |
4 | 4 | <a-tabs :activeKey="customActiveKey" :tabBarStyle="{ textAlign: 'center', borderBottom: 'unset' }" @change="handleTabClick"> |
5 | - <a-tab-pane key="tab1" tab="激活码授权"> | |
6 | - <!-- <login-account ref="alogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-account> --> | |
7 | - </a-tab-pane> | |
8 | - <!-- <a-tab-pane key="tab2" tab="手机号登录"> | |
9 | - <login-phone ref="plogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-phone> | |
10 | - </a-tab-pane> --> | |
5 | + <a-tab-pane key="tab1" tab="激活码授权"/> | |
11 | 6 | </a-tabs> |
12 | 7 | <a-form-model-item> |
13 | 8 | <a-input size="large" v-model="model.activationCode" autocomplete="false" placeholder="请输入激活码"/> |
... | ... | @@ -18,12 +13,9 @@ |
18 | 13 | </a-form-item> |
19 | 14 | </a-form-model> |
20 | 15 | <two-step-captcha v-if="requiredTwoStepCaptcha" :visible="stepCaptchaVisible" @success="stepCaptchaSuccess" @cancel="stepCaptchaCancel"></two-step-captcha> |
21 | - <!-- <login-select-tenant ref="loginSelect" @success="loginSelectOk"></login-select-tenant> --> | |
22 | - <!-- <third-login ref="thirdLogin"></third-login>--> | |
23 | 16 | </div> |
24 | 17 | </template> |
25 | 18 | |
26 | - | |
27 | 19 | <script> |
28 | 20 | import Vue from 'vue' |
29 | 21 | import {ACCESS_TOKEN, ENCRYPTED_STRING} from '@/store/mutation-types' |
... | ... | @@ -51,11 +43,6 @@ export default { |
51 | 43 | model: { |
52 | 44 | activationCode: '' |
53 | 45 | }, |
54 | - validatorRules: { | |
55 | - activationCode: [{ | |
56 | - required: true, message: '请输入激活码', validator: 'click' | |
57 | - }], | |
58 | - } | |
59 | 46 | } |
60 | 47 | }, |
61 | 48 | created() { |
... | ... | @@ -79,27 +66,6 @@ export default { |
79 | 66 | } |
80 | 67 | }) |
81 | 68 | }, |
82 | - // 验证字段 | |
83 | - validateFields(arr, callback) { | |
84 | - let promiseArray = [] | |
85 | - for (let item of arr) { | |
86 | - let p = new Promise((resolve, reject) => { | |
87 | - this.$refs['form'].validateField(item, (err) => { | |
88 | - if (!err) { | |
89 | - resolve(); | |
90 | - } else { | |
91 | - reject(err); | |
92 | - } | |
93 | - }) | |
94 | - }); | |
95 | - promiseArray.push(p) | |
96 | - } | |
97 | - Promise.all(promiseArray).then(() => { | |
98 | - callback() | |
99 | - }).catch(err => { | |
100 | - callback(err) | |
101 | - }) | |
102 | - }, | |
103 | 69 | //验证激活码 |
104 | 70 | handleSubmit() { |
105 | 71 | this.loginBtn = true; |
... | ... | @@ -110,13 +76,11 @@ export default { |
110 | 76 | this.$router.push({path: "/user/login"}); |
111 | 77 | this.$notification.success({ |
112 | 78 | message: '激活成功,请重新登录', |
113 | - // description: `${timeFix()},欢迎回来`, | |
114 | 79 | }); |
115 | 80 | }, |
116 | 81 | systemActivationSuccessError(message) { |
117 | 82 | this.$notification.error({ |
118 | 83 | message: message, |
119 | - // description: `${timeFix()},欢迎回来`, | |
120 | 84 | }); |
121 | 85 | this.loginBtn = false; |
122 | 86 | }, |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java
1 | 1 | package org.jeecg.modules.system.controller; |
2 | 2 | |
3 | 3 | import java.io.File; |
4 | +import java.io.FileInputStream; | |
4 | 5 | import java.io.FileOutputStream; |
5 | 6 | import java.io.IOException; |
6 | 7 | import java.util.ArrayList; |
... | ... | @@ -14,6 +15,7 @@ import java.util.Map; |
14 | 15 | import javax.servlet.http.HttpServletRequest; |
15 | 16 | import javax.servlet.http.HttpServletResponse; |
16 | 17 | |
18 | +import org.apache.commons.io.IOUtils; | |
17 | 19 | import org.apache.shiro.SecurityUtils; |
18 | 20 | import org.jeecg.common.api.vo.Result; |
19 | 21 | import org.jeecg.common.constant.CacheConstant; |
... | ... | @@ -41,8 +43,8 @@ import org.jeecg.modules.system.service.ISysTenantService; |
41 | 43 | import org.jeecg.modules.system.service.ISysUserService; |
42 | 44 | import org.jeecg.modules.system.util.RandImageUtil; |
43 | 45 | import org.jeecg.utils.HuahengJwtUtil; |
46 | +import org.jeecg.utils.HuahengRedisUtil; | |
44 | 47 | import org.jeecg.utils.StringUtils; |
45 | -import org.jeecg.utils.support.ApiAuthentication; | |
46 | 48 | import org.jeecg.utils.support.SystemRSA256Key; |
47 | 49 | import org.springframework.beans.BeanUtils; |
48 | 50 | import org.springframework.beans.factory.annotation.Autowired; |
... | ... | @@ -67,6 +69,7 @@ import com.auth0.jwt.JWT; |
67 | 69 | import com.auth0.jwt.JWTVerifier; |
68 | 70 | import com.auth0.jwt.algorithms.Algorithm; |
69 | 71 | import com.auth0.jwt.exceptions.JWTVerificationException; |
72 | +import com.auth0.jwt.exceptions.TokenExpiredException; | |
70 | 73 | import com.auth0.jwt.interfaces.DecodedJWT; |
71 | 74 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
72 | 75 | import com.baomidou.mybatisplus.core.toolkit.IdWorker; |
... | ... | @@ -111,6 +114,9 @@ public class LoginController { |
111 | 114 | |
112 | 115 | @Autowired |
113 | 116 | private BaseCommonService baseCommonService; |
117 | + | |
118 | + @Autowired | |
119 | + private HuahengRedisUtil huahengRedisUtil; | |
114 | 120 | |
115 | 121 | @ApiOperation("登录接口") |
116 | 122 | @RequestMapping(value = "/login", method = RequestMethod.POST) |
... | ... | @@ -163,10 +169,10 @@ public class LoginController { |
163 | 169 | return result; |
164 | 170 | } |
165 | 171 | // 激活信息认证 |
166 | -// result = HuahengJwtUtil.checkSystemActivationCode(); | |
167 | -// if (!result.isSuccess()) { | |
168 | -// return result; | |
169 | -// } | |
172 | + result = this.checkSystemActivationCode(); | |
173 | + if (!result.isSuccess()) { | |
174 | + return result; | |
175 | + } | |
170 | 176 | // 用户登录信息 |
171 | 177 | result = userInfo(sysUser, warehouseCode); |
172 | 178 | // update-begin--Author:liusq Date:20210126 for:登录成功,删除redis中的验证码 |
... | ... | @@ -193,16 +199,15 @@ public class LoginController { |
193 | 199 | JWTVerifier verifier = |
194 | 200 | JWT.require(algorithm).withClaim("operator", HuahengJwtUtil.HUAHENG_SYSTEM_ID).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); |
195 | 201 | DecodedJWT jwt = verifier.verify(systemActivationModel.getActivationCode()); |
196 | - new ApiAuthentication.ApiAuthenticationBuild().operator(jwt.getClaim("operator").asString()).audience(jwt.getAudience().get(0)).issuer(jwt.getIssuer()) | |
197 | - .issuedAt(jwt.getIssuedAt()).expireDateTime(jwt.getExpiresAt()).bulid(); | |
198 | - | |
199 | 202 | // 验证通过写入文件 |
200 | 203 | File file = new File(System.getProperties().getProperty("user.dir") + File.separatorChar + HuahengJwtUtil.SYSTEM_ACTIVATION_CODE_FILE_NAME); |
201 | 204 | outputStream = new FileOutputStream(file, false); |
202 | 205 | FileCopyUtils.copy(systemActivationModel.getActivationCode().getBytes(), outputStream); |
206 | + // 验证通过写入Redis | |
207 | + huahengRedisUtil.setWithNoExpirationTime(HuahengJwtUtil.SYSTEM_ACTIVATION_CODE_KEY, systemActivationModel.getActivationCode()); | |
203 | 208 | } catch (JWTVerificationException e) { |
204 | 209 | log.error(e.getMessage()); |
205 | - result.error500("激活失败"); | |
210 | + result.error500("系统激活码无效"); | |
206 | 211 | return result; |
207 | 212 | } finally { |
208 | 213 | if (outputStream != null) { |
... | ... | @@ -212,6 +217,58 @@ public class LoginController { |
212 | 217 | result.setMessage("激活成功"); |
213 | 218 | return result; |
214 | 219 | } |
220 | + | |
221 | + private Result<JSONObject> checkSystemActivationCode() throws IOException { | |
222 | + Result<JSONObject> result = new Result<JSONObject>(); | |
223 | + FileInputStream inputStream = null; | |
224 | + FileOutputStream outputStream = null; | |
225 | + try { | |
226 | + String activationCode = null; | |
227 | + File file = new File(System.getProperties().getProperty("user.dir") + File.separatorChar + HuahengJwtUtil.SYSTEM_ACTIVATION_CODE_FILE_NAME); | |
228 | + if (file.exists()) { | |
229 | + inputStream = new FileInputStream(file); | |
230 | + activationCode = IOUtils.toString(inputStream, "utf-8"); | |
231 | + } | |
232 | + String redisActivationCode = huahengRedisUtil.get(HuahengJwtUtil.SYSTEM_ACTIVATION_CODE_KEY, String.class); | |
233 | + // 文件激活码为空或redis中的激活码与文件中的激活码不一致,更新文件激活码 | |
234 | + if (!StringUtils.isEmpty(redisActivationCode) && (StringUtils.isEmpty(activationCode) || !activationCode.equals(redisActivationCode))) { | |
235 | + activationCode = redisActivationCode; | |
236 | + outputStream = new FileOutputStream(file, false); | |
237 | + FileCopyUtils.copy(activationCode.getBytes(), outputStream); | |
238 | + } | |
239 | + if (StringUtils.isEmpty(activationCode)) { | |
240 | + result.setSuccess(false); | |
241 | + result.setCode(499); | |
242 | + result.setMessage("系统激活码无效"); | |
243 | + return result; | |
244 | + } | |
245 | + // 验证激活码 | |
246 | + Algorithm algorithm = Algorithm.RSA256(new SystemRSA256Key().getPublicKey(), new SystemRSA256Key().getPrivateKey()); | |
247 | + JWTVerifier verifier = | |
248 | + JWT.require(algorithm).withClaim("operator", HuahengJwtUtil.HUAHENG_SYSTEM_ID).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); | |
249 | + DecodedJWT jwt = verifier.verify(activationCode); | |
250 | + // 如果redis中不存在激活码 则写入redis | |
251 | + if (StringUtils.isEmpty(redisActivationCode) || !redisActivationCode.equals(activationCode)) { | |
252 | + huahengRedisUtil.setWithNoExpirationTime(HuahengJwtUtil.SYSTEM_ACTIVATION_CODE_KEY, activationCode); | |
253 | + } | |
254 | + } catch (TokenExpiredException e) { | |
255 | + result.setSuccess(false); | |
256 | + result.setCode(499); | |
257 | + result.setMessage("系统激活码使用期限已到期"); | |
258 | + } catch (Exception e) { | |
259 | + result.setSuccess(false); | |
260 | + result.setCode(499); | |
261 | + result.setMessage("系统激活码无效"); | |
262 | + } finally { | |
263 | + if (inputStream != null) { | |
264 | + inputStream.close(); | |
265 | + } | |
266 | + if (outputStream != null) { | |
267 | + outputStream.close(); | |
268 | + } | |
269 | + } | |
270 | + return result; | |
271 | + } | |
215 | 272 | |
216 | 273 | @Bean |
217 | 274 | public ResourceLoader createResourceLoader() { |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java
1 | 1 | package org.jeecg.utils; |
2 | 2 | |
3 | -import java.io.File; | |
4 | -import java.io.FileInputStream; | |
5 | -import java.io.IOException; | |
6 | -import java.io.InputStream; | |
7 | 3 | import java.lang.reflect.Field; |
8 | 4 | import java.util.Arrays; |
9 | 5 | import java.util.Date; |
... | ... | @@ -12,9 +8,7 @@ import java.util.UUID; |
12 | 8 | |
13 | 9 | import javax.servlet.http.HttpServletRequest; |
14 | 10 | |
15 | -import org.apache.commons.io.IOUtils; | |
16 | 11 | import org.apache.shiro.SecurityUtils; |
17 | -import org.jeecg.common.api.vo.Result; | |
18 | 12 | import org.jeecg.common.exception.JeecgBootException; |
19 | 13 | import org.jeecg.common.system.vo.LoginUser; |
20 | 14 | import org.jeecg.common.util.oConvertUtils; |
... | ... | @@ -25,12 +19,10 @@ import org.jeecg.utils.support.SystemRSA256Key; |
25 | 19 | import org.springframework.stereotype.Component; |
26 | 20 | import org.springframework.util.CollectionUtils; |
27 | 21 | |
28 | -import com.alibaba.fastjson.JSONObject; | |
29 | 22 | import com.auth0.jwt.JWT; |
30 | 23 | import com.auth0.jwt.JWTVerifier; |
31 | 24 | import com.auth0.jwt.algorithms.Algorithm; |
32 | 25 | import com.auth0.jwt.exceptions.JWTDecodeException; |
33 | -import com.auth0.jwt.exceptions.TokenExpiredException; | |
34 | 26 | import com.auth0.jwt.interfaces.DecodedJWT; |
35 | 27 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
36 | 28 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
... | ... | @@ -57,6 +49,8 @@ public class HuahengJwtUtil { |
57 | 49 | public static final String ALL_WAREHOUSE_CODE = "ALL_WAREHOUSE"; |
58 | 50 | |
59 | 51 | public static final String SYSTEM_ACTIVATION_CODE_FILE_NAME = "ActivationCode.txt"; |
52 | + | |
53 | + public static final String SYSTEM_ACTIVATION_CODE_KEY = "ActivationCode"; | |
60 | 54 | |
61 | 55 | /** |
62 | 56 | * 根据request中的token获取用户账号 |
... | ... | @@ -266,36 +260,6 @@ public class HuahengJwtUtil { |
266 | 260 | } |
267 | 261 | } |
268 | 262 | |
269 | - public static Result<JSONObject> checkSystemActivationCode() throws IOException { | |
270 | - Result<JSONObject> result = new Result<JSONObject>(); | |
271 | - InputStream inputStream = null; | |
272 | - try { | |
273 | - File file = new File(System.getProperties().getProperty("user.dir") + File.separatorChar + SYSTEM_ACTIVATION_CODE_FILE_NAME); | |
274 | - inputStream = new FileInputStream(file); | |
275 | - // 获得激活码 | |
276 | - String activationCode = IOUtils.toString(inputStream, "utf-8"); | |
277 | - Algorithm algorithm = Algorithm.RSA256(new SystemRSA256Key().getPublicKey(), new SystemRSA256Key().getPrivateKey()); | |
278 | - JWTVerifier verifier = | |
279 | - JWT.require(algorithm).withClaim("operator", HuahengJwtUtil.HUAHENG_SYSTEM_ID).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); | |
280 | - DecodedJWT jwt = verifier.verify(activationCode); | |
281 | - new ApiAuthentication.ApiAuthenticationBuild().operator(jwt.getClaim("operator").asString()).audience(jwt.getAudience().get(0)).issuer(jwt.getIssuer()) | |
282 | - .issuedAt(jwt.getIssuedAt()).expireDateTime(jwt.getExpiresAt()).bulid(); | |
283 | - } catch (TokenExpiredException e) { | |
284 | - result.setSuccess(false); | |
285 | - result.setCode(499); | |
286 | - result.setMessage("系统激活码使用期限已到期"); | |
287 | - } catch (Exception e) { | |
288 | - result.setSuccess(false); | |
289 | - result.setCode(499); | |
290 | - result.setMessage("系统激活码无效"); | |
291 | - } finally { | |
292 | - if (inputStream != null) { | |
293 | - inputStream.close(); | |
294 | - } | |
295 | - } | |
296 | - return result; | |
297 | - } | |
298 | - | |
299 | 263 | /** |
300 | 264 | * 生成第三方系统HTTP访问TOKEN |
301 | 265 | * @author TanYibin |
... | ... |
huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengRedisUtil.java
... | ... | @@ -99,6 +99,21 @@ public class HuahengRedisUtil { |
99 | 99 | log.error("操作缓存异常:key:{}", key, e); |
100 | 100 | } |
101 | 101 | } |
102 | + | |
103 | + /** | |
104 | + * 设置key,value 无过期时间 | |
105 | + * @author TanYibin | |
106 | + * @createDate 2023年2月8日 | |
107 | + * @param key | |
108 | + * @param value | |
109 | + */ | |
110 | + public void setWithNoExpirationTime(@Nonnull String key, @Nonnull Object value) { | |
111 | + try { | |
112 | + redisTemplate.opsForValue().set(key, toJson(value)); | |
113 | + } catch (Exception e) { | |
114 | + log.error("操作缓存异常:key:{}", key, e); | |
115 | + } | |
116 | + } | |
102 | 117 | |
103 | 118 | /** |
104 | 119 | * 设置key,value,过期时间 |
... | ... |
huaheng-wms-core/src/main/resources/application-dev.yml
huaheng-wms-core/src/main/resources/application-prod.yml