123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- package com.beifan.foxlibc.modules.controller;
- import com.beifan.foxlibc.framework.utils.Assert;
- import com.beifan.foxlibc.framework.utils.JvmCache;
- import com.beifan.foxlibc.framework.utils.R;
- import com.beifan.foxlibc.framework.utils.StringUtils;
- import com.beifan.foxlibc.framework.utils.generator.UniqueUtils;
- import com.beifan.foxlibc.framework.utils.generator.VerifyCodes;
- import com.beifan.foxlibc.framework.utils.security.DoubleCoder;
- import com.beifan.foxlibc.framework.utils.time.DateUtils;
- import com.beifan.foxlibc.framework.utils.time.TimeUnits;
- import com.beifan.foxlibc.modules.configuration.NV_TOKEN;
- import com.beifan.foxlibc.modules.pojo.model.SystemSet;
- import com.beifan.foxlibc.modules.pojo.model.User;
- import com.beifan.foxlibc.modules.pojo.model.UserLogininfo;
- import com.beifan.foxlibc.modules.pojo.webio.MakeVerificationCodeIn;
- import com.beifan.foxlibc.modules.pojo.webio.ResetPasswdIn;
- import com.beifan.foxlibc.modules.pojo.webio.ResetSecPasswdIn;
- import com.beifan.foxlibc.modules.pojo.webio.io.AuthenticationCodeIn;
- import com.beifan.foxlibc.modules.pojo.webio.io.AuthenticationOut;
- import com.beifan.foxlibc.modules.pojo.webio.io.AuthenticationSecUserIn;
- import com.beifan.foxlibc.modules.pojo.webio.io.AuthenticationUserIn;
- import com.beifan.foxlibc.modules.service.UserOperateService;
- import com.beifan.foxlibc.modules.service.UserService;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestHeader;
- import org.springframework.web.bind.annotation.RestController;
- import javax.validation.Valid;
- import java.util.Date;
- import java.util.Map;
- import java.util.Objects;
- import java.util.regex.Pattern;
- /**
- * 认证服务:登录/code生成/解析/验证
- *
- * @author lts
- */
- @RestController
- @Slf4j
- public class AuthenticationController {
- @Autowired
- private UserService userService;
- @Autowired
- private UserOperateService userOperateService;
- // @Value("${foxlibc.debug}") private boolean __DEBUG__;
- @Value("${foxlibc.mlogin:false}")
- private boolean __M_LOGIN__;
- /**
- * 缓存
- */
- private final JvmCache jvmCache = new JvmCache();
- /* 密码校验规则 */
- static String PWD_VALID_RGX =
- "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[`!@#$%^&*()_+{}\":?><,./';\\[\\]=-\\\\|])(?=\\S+$).{8,20}$";
- /**
- * 生成appToken
- */
- @NV_TOKEN
- @PostMapping("/application-token")
- public R<AuthenticationOut> applicationToken(@Valid @RequestBody AuthenticationCodeIn authenticationCodeIn) {
- Assert.throwIfBool(userService.application(authenticationCodeIn.getAppid(), authenticationCodeIn.getAppSecret()),
- "appid或app secret不正确");
- // authenticationService.useEnv(JwtConst.APP);
- // String appToken = authenticationService.createToken(Maps.ofMap(JwtConst.APP, authenticationCodeIn.getAppid()));
- String appToken = UniqueUtils.uuid().toLowerCase();
- Date expireTime = DateUtils.plus(new Date(), 1, TimeUnits.DAYS);
- /* 记录登录信息 */
- // Date expireTime = authenticationService.getExpireTime(appToken);
- String appid = authenticationCodeIn.getAppid();
- UserLogininfo userLogininfo = new UserLogininfo(appid, null, expireTime, appToken, null, null, null);
- userService.saveUserLogininfo(userLogininfo);
- SystemSet systemSet = userService.systemSetting();
- Boolean verificationCode = systemSet.getVerificationCode();
- return R.ok(
- "appToken", appToken,
- "expireTime", DateUtils.format(expireTime),
- "verificationCode", verificationCode
- );
- }
- /**
- * 验证token
- */
- @NV_TOKEN
- @PostMapping("/valid/token")
- public R<AuthenticationOut> validToken(@RequestHeader Map<String, String> headers) {
- String token = headers.get("authorization");
- String authId = headers.get("authid");
- /* WRAN: 异常信息中的 -C401 是指定返回Code。
- 如果删除了前端将不能通过 401 判断用户是否过期 */
- // Assert.throwIfBool(!jvmCache.contains(CacheConst.TOKEN_BLACKLIST(code)), "-C401 TOKEN已被禁用");
- /* 如果验证失败,抛出异常 */
- // Assert.throwIfBool(authenticationService.validate(code), "-C401 TOKEN已过期");
- UserLogininfo userLogininfo = userService.queryUserLogininfo(token);
- Date expireTime = userLogininfo.getExpireTime();
- Assert.throwIfBool(!DateUtils.gteq(new Date(), expireTime), "-C401 TOKEN已过期");
- if (Objects.nonNull(authId)) {
- userOperateService.operateLog(userLogininfo.getUserId(), authId);
- }
- return R.ok();
- }
- /**
- * 生成验证码
- */
- @NV_TOKEN
- @PostMapping("/verification-code")
- public R<String> verificationCode(@Valid @RequestBody MakeVerificationCodeIn makeVerificationCodeIn) {
- String code;
- SystemSet systemSet = userService.systemSetting();
- int vlen = Integer.parseInt(systemSet.getVerificationCodeLength());
- /* true 只有数字,false 数字加字符 */
- if (SystemSet.ONLY_NUMBER.equals(systemSet.getVerificationCodeType())) {
- code = VerifyCodes.randomSimpleVerifyCode(vlen);
- } else {
- code = VerifyCodes.randomComplexVerifyCode(vlen);
- }
- Date codeExpireTime = DateUtils.plus(new Date(), 60, TimeUnits.SECONDS);
- // jvmCache.set(CacheConst.VERIFICATION_CODE(makeVerificationCodeIn.getAppToken()), code, (60 * 3));
- String appToken = makeVerificationCodeIn.getAppToken();
- UserLogininfo userLogininfo = userService.queryUserLogininfo(appToken);
- userLogininfo.setVerificationCode(code);
- userLogininfo.setCodeExpireTime(codeExpireTime);
- userService.updateUserLogininfo(userLogininfo, appToken);
- return R.ok(code);
- }
- /**
- * 用户登录
- */
- @NV_TOKEN
- @PostMapping("/sign-in")
- public R<AuthenticationOut> signin(@RequestHeader("Authorization") String appToken, @Valid @RequestBody AuthenticationUserIn authenticationUserIn) {
- // String sessionid = getSessionId();
- String username = authenticationUserIn.getUsername();
- SystemSet systemSet = userService.systemSetting();
- /* 验证码校验 */
- // String verificationCode = jvmCache.get(CacheConst.VERIFICATION_CODE(appToken));
- UserLogininfo userLogininfo = userService.queryUserLogininfo(appToken);
- if (systemSet.getVerificationCode()) {
- String verificationCode = userLogininfo.getVerificationCode();
- Assert.throwIfBool(verificationCode != null && verificationCode.equals(authenticationUserIn.getVerificationCode()), "验证码错误");
- boolean isCheckFull = systemSet.getVerificationCodeAa() ?
- Objects.equals(verificationCode, authenticationUserIn.getVerificationCode()) :
- Objects.equals(verificationCode.toLowerCase(), authenticationUserIn.getVerificationCode().toLowerCase());
- Assert.throwIfBool(isCheckFull, "验证码不正确");
- Date codeExpireTime = userLogininfo.getCodeExpireTime();
- Assert.throwIfBool(!DateUtils.gteq(new Date(), codeExpireTime), "-C401 验证码已过期");
- }
- // 查询用户
- User u = userService.queryUserByUsername(username);
- Assert.throwIfBool(!"0".equals(u.getUserStatus()), "当前用户状态已被禁用, 不允许登录");
- String userid;
- try {
- /* 验证用户名密码是否可以登录 */
- userid = userService.sign(username, authenticationUserIn.getPassword());
- // 验证成功则清零失败次数
- userService.updateFailCount(username, 0);
- } catch (Exception e) {
- // 验证失败 更新失败次数
- if (u.getFailCount() < 4) {
- userService.updateFailCount(username, u.getFailCount() + 1);
- } else {
- // 超过次数则禁用用户,并且错误次数重置为0
- userService.updateStatus(username, "0");
- userService.updateFailCount(username, 0);
- }
- // 并且抛出异常
- throw e;
- }
- /* 生成token */
- // authenticationService.useEnv(JwtConst.USR);
- // String token = authenticationService.createToken(Maps.ofMap(JwtConst.USR_ID, userid));
- // Date tokenDate = authenticationService.getExpireTime(token);
- String token = UniqueUtils.uuid().toLowerCase();
- Date tokenDate = DateUtils.plus(new Date(), 1, TimeUnits.DAYS);
- UserLogininfo appLoginInfo = userService.queryUserLogininfo(appToken);
- appLoginInfo.setVerificationCode(null);
- appLoginInfo.setCodeExpireTime(null);
- appLoginInfo.setUserId(userid);
- appLoginInfo.setToken(token);
- appLoginInfo.setExpireTime(tokenDate);
- /* 如果不允许其他地方登陆的话,删除其他地方登录过的缓存 */
- if (Boolean.FALSE.equals(systemSet.getAllowMultipleMachineLogins())) {
- userService.deleteUserLogininfoByUserId(userid);
- }
- /* 保存登录信息 */
- userService.updateUserLogininfo(appLoginInfo, appToken);
- return R.ok(
- "token", token,
- "userid", userid,
- "date", tokenDate
- );
- }
- /**
- * 刷新token
- */
- @PostMapping("/flush-token")
- public R<Void> flushToken(@RequestHeader("Authorization") String token) {
- // String sessionid = getSessionId();
- // String env = authenticationService.getEnv(token);
- UserLogininfo userLogininfo = userService.queryUserLogininfo(token);
- Date expireTime = DateUtils.plus(new Date(), 1, TimeUnits.DAYS);
- userLogininfo.setExpireTime(expireTime);
- userService.updateUserLogininfo(userLogininfo, token);
- return R.ok("expireTime", DateUtils.format(expireTime));
- }
- /**
- * 退出登录
- */
- @PostMapping("/sign-out")
- public R<Void> signout(@RequestHeader("Authorization") String token) {
- /* 添加到黑名单 */
- // Date expireTime = authenticationService.getExpireTime(token);
- // jvmCache.set(CacheConst.TOKEN_BLACKLIST(token), 0, expireTime);
- /* 删除登录日志中的数据 */
- userService.deleteUserLogininfoByToken(token);
- return R.ok();
- }
- /**
- * 获取系统设置
- */
- @PostMapping("/system/setting")
- public R<SystemSet> systemSet() {
- return R.ok(userService.systemSetting());
- }
- /**
- * 用户登录
- */
- @NV_TOKEN
- @PostMapping("/sec-sign-in")
- public R<AuthenticationOut> secsignin(@Valid @RequestBody AuthenticationSecUserIn authenticationUserIn) {
- String userId = authenticationUserIn.getUserId();
- SystemSet systemSet = userService.systemSetting();
- UserLogininfo userLogininfos = userService.queryUserLogininfosByUserIdPS(userId);
- if (systemSet.getVerificationCode()) {
- String verificationCode = userLogininfos.getVerificationCode();
- Assert.throwIfBool(verificationCode != null && verificationCode.equals(authenticationUserIn.getVerificationCode()), "验证码错误");
- boolean isCheckFull = systemSet.getVerificationCodeAa() ?
- Objects.equals(verificationCode, authenticationUserIn.getVerificationCode()) :
- Objects.equals(verificationCode.toLowerCase(), authenticationUserIn.getVerificationCode().toLowerCase());
- Assert.throwIfBool(isCheckFull, "验证码不正确");
- Date codeExpireTime = userLogininfos.getCodeExpireTime();
- Assert.throwIfBool(!DateUtils.gteq(new Date(), codeExpireTime), "-C401 验证码已过期");
- }
- /* 验证用户名密码是否可以登录 */
- String userid = userService.secsign(userId, authenticationUserIn.getPassword());
- return R.ok(
- "userid", userid
- );
- }
- // /**
- // * 获取系统设置
- // */
- // @PostMapping("/authQuery")
- // public R<SystemSet> authQuery(@RequestHeader("Authorization") String token)
- // {
- // String userid = authenticationService.claimsValue(token, JwtConst.USR_ID);
- // return R.ok(userService.authQuery(userid));
- // }
- //
- /**
- * 修改用户密码
- */
- @PostMapping("/reset-passwd")
- public R<Void> resetPasswd(@Valid @RequestBody ResetPasswdIn resetPasswdIn) {
- String userid = userService.idsign(resetPasswdIn.getUserId(), resetPasswdIn.getOriginPassword());
- SystemSet systemSet = userService.systemSetting();
- String pwdMatch = systemSet.getPwdCons();
- /* 修改密码 */
- User user = userService.userQuery(userid);
- user.setUserPwd(resetPasswdIn.getNewPassword());
- Assert.throwIfBool(Pattern.matches(pwdMatch, user.getUserPwd()), "密码不符合规则");
- String pwd = StringUtils.toLowerCase(DoubleCoder.MD5(resetPasswdIn.getNewPassword()));
- userService.updateUserPwd(userid, pwd);
- return R.ok();
- }
- /**
- * 修改用户密码
- */
- @PostMapping("/reset-secpasswd")
- public R<Void> resetSecPasswd(@Valid @RequestBody ResetSecPasswdIn resetPasswdIn) {
- String userid = resetPasswdIn.getUserId();
- /* 修改密码 */
- User user = userService.userQuery(userid);
- user.setUserPwd(resetPasswdIn.getNewPassword());
- SystemSet systemSet = userService.systemSetting();
- String pwdMatch = systemSet.getPwdCons();
- Assert.throwIfBool(Pattern.matches(pwdMatch, user.getUserPwd()), "密码不符合规则");
- String pwd = StringUtils.toLowerCase(DoubleCoder.MD5(resetPasswdIn.getNewPassword()));
- userService.updateUserSecPwd(userid, pwd);
- return R.ok();
- }
- // private String getSessionId() { return WebRequests.getHttpServletRequest().getSession().getId(); }
- }
|