package com.jilongda.applet.controller;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.alipay.v3.ApiException;
|
import com.aliyuncs.exceptions.ClientException;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.dingtalk.api.DefaultDingTalkClient;
|
import com.dingtalk.api.DingTalkClient;
|
import com.dingtalk.api.request.OapiUserGetuserinfoRequest;
|
import com.dingtalk.api.request.OapiV2UserGetRequest;
|
import com.dingtalk.api.response.OapiUserGetuserinfoResponse;
|
import com.dingtalk.api.response.OapiV2UserGetResponse;
|
import com.github.xiaoymin.knife4j.core.util.StrUtil;
|
import com.jilongda.applet.dto.*;
|
import com.jilongda.applet.model.SecUser;
|
import com.jilongda.applet.security.SecurityUserDetails;
|
import com.jilongda.applet.security.SysUserDetailsService;
|
import com.jilongda.applet.service.SecUserService;
|
import com.jilongda.applet.utils.ALiSendSms;
|
import com.jilongda.applet.utils.LoginInfoUtil;
|
import com.jilongda.applet.utils.dingding.DingTalkAccessTokenRequest;
|
import com.jilongda.common.basic.ApiResult;
|
import com.jilongda.common.basic.Constant;
|
import com.jilongda.common.exception.ServiceException;
|
import com.jilongda.common.log.OperLoginLog;
|
import com.jilongda.common.log.OperationLog;
|
import com.jilongda.common.msg.HuaweiCloudSMSUtil;
|
import com.jilongda.common.redis.RedisAutoTemplate;
|
import com.jilongda.common.security.SecurityUtils;
|
import com.jilongda.common.utils.WebUtils;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.BadCredentialsException;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.util.Assert;
|
import org.springframework.util.StringUtils;
|
import org.springframework.validation.annotation.Validated;
|
import org.springframework.web.bind.annotation.*;
|
|
import java.util.HashMap;
|
import java.util.Map;
|
import java.util.Objects;
|
|
/**
|
* <p>
|
* 会员表 前端控制器
|
* </p>
|
*
|
* @author xiaochen
|
* @since 2021-07-28
|
*/
|
@Slf4j
|
@Api(tags = "用户登录相关")
|
@RestController
|
@RequestMapping("/")
|
public class LoginController {
|
private final SecurityUtils securityUtils;
|
private final AuthenticationManager authenticationManager;
|
private final RedisAutoTemplate redisAutoTemplate;
|
private final HuaweiCloudSMSUtil msgUtils;
|
private final LoginInfoUtil loginInfoUtil;
|
private final SysUserDetailsService loadUserDetailsService;
|
@Autowired
|
private SecUserService secUserService;
|
@Autowired
|
private PasswordEncoder passwordEncoder;
|
|
@Autowired
|
public LoginController(SecurityUtils securityUtils, AuthenticationManager authenticationManager, RedisAutoTemplate redisAutoTemplate, HuaweiCloudSMSUtil msgUtils, LoginInfoUtil loginInfoUtil,SysUserDetailsService loadUserDetailsService) {
|
this.securityUtils = securityUtils;
|
this.authenticationManager = authenticationManager;
|
this.redisAutoTemplate = redisAutoTemplate;
|
this.msgUtils = msgUtils;
|
this.loginInfoUtil = loginInfoUtil;
|
this.loadUserDetailsService = loadUserDetailsService;
|
}
|
|
// @ApiOperation(value = "通过code获得openid")
|
// @GetMapping("openId-by-jscode2session/{code}")
|
// public ApiResult<Map<String, Object>> jscode2session(@PathVariable("code") String code) {
|
//// log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", code);
|
//// WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig);
|
//// Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(code));
|
//// String openid = body.getOpenid();
|
//// String sessionKey = body.getSessionKey();
|
//// SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getOpenId, openid).last("limit 1"));
|
//// if (Objects.isNull(secUser)) {
|
//// return ApiResult.failed(500, "请绑定账号");
|
//// }
|
//// // 提前对sessionKey进行删除
|
//// //redisTemplate.delete(openid);
|
//// log.info("换取sessionKey:{}", sessionKey);
|
//// // 将sessionKey进行存储,后续获取信息需要
|
//// redisAutoTemplate.setStr(openid, sessionKey);
|
// Map<String, Object> tokenInfos = securityUtils.login(null, null, authenticationManager, SecUser.class, 3);
|
// return ApiResult.success(tokenInfos);
|
// }
|
|
// @ApiOperation(value = "账号与小程序进行绑定")
|
// @GetMapping("openidBindPhone/{code}/{account}")
|
// public ApiResult<String> openidBindPhone(@PathVariable("code") String code, @PathVariable("account") String account) {
|
// SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getAccount, account).last("limit 1"));
|
// Assert.isTrue(!StringUtils.hasLength(secUser.getOpenId()), "该账号已绑定微信");
|
// log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", code);
|
// WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig);
|
// Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(code));
|
// String openid = body.getOpenid();
|
// // 手机号绑定微信
|
// secUser.setOpenId(openid);
|
// secUserService.updateById(secUser);
|
// return ApiResult.success();
|
// }
|
/**
|
* 登录接口
|
*/
|
// @OperLoginLog
|
// @ApiOperation("用户账号登录")
|
// @PostMapping(value = "login")
|
// public ApiResult<Map<String, Object>> login(@Validated @RequestBody LoginDTO loginDto) {
|
// // 先检验是否登录
|
// String username = loginDto.getAccount();
|
// String password = loginDto.getPassword();
|
//
|
// log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", loginDto.getCode());
|
//// WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig);
|
//// Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(loginDto.getCode()));
|
//// String openid = body.getOpenid();
|
//// loginDto.setOpenId(openid);
|
//
|
// try {
|
// Map<String, Object> token = securityUtils.login(username, password, authenticationManager, SecurityUserDetails.class, 2);
|
// return ApiResult.success(token);
|
// } catch (Exception e) {
|
// e.printStackTrace();
|
// ApiResult<Map<String, Object>> failed = ApiResult.failed(new HashMap<>(1));
|
// failed.setCode(0);
|
// failed.setSuccess(false);
|
// failed.setMsg(e.getMessage());
|
// return failed;
|
// }
|
// }
|
|
/**
|
* 登录接口
|
*/
|
@OperLoginLog
|
@ApiOperation("后台登录")
|
@PostMapping(value = "login")
|
public ApiResult<Map<String, Object>> login1(@Validated @RequestBody LoginDTO loginDto) {
|
//验证是否通过验证
|
// if (ObjectUtils.isEmpty(loginDto.getVerify()) || !loginDto.getVerify()) {
|
// ApiResult<Map<String, Object>> failed = new ApiResult<>();
|
// failed.setMsg("登录失败,请正确验证!");
|
// return failed;
|
// }
|
// 先检验是否登录
|
String username = loginDto.getPhone();
|
String password = loginDto.getPassword();
|
try {
|
SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
|
.eq(SecUser::getAccount, loginDto.getPhone()));
|
Assert.isTrue(Objects.nonNull(secUser), "该账号不存在");
|
|
|
SecUser one = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getAccount, username));
|
if (one.getState()){
|
return ApiResult.failed(500, "该账号已被冻结,请联系管理员");
|
}
|
|
|
Map<String, Object> token = securityUtils.login(username, password, authenticationManager, SecurityUserDetails.class, 1);
|
return ApiResult.success(token);
|
} catch (Exception e) {
|
ApiResult<Map<String, Object>> failed = ApiResult.failed(new HashMap<>(1));
|
failed.setCode(0);
|
failed.setSuccess(false);
|
failed.setMsg(e.getMessage());
|
return failed;
|
}
|
}
|
|
/**
|
* 登录接口
|
*/
|
// @OperLoginLog
|
// @ApiOperation("选择用户账号登录")
|
// @PostMapping(value = "choose-login")
|
// public ApiResult<Map<String, Object>> chooseLogin(@Validated @RequestBody LoginDTO loginDto) {
|
// 先检验是否登录
|
// String username = loginDto.getAccount();
|
//
|
//// SecUser one = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
|
//// .eq(SecUser::getAccount, username));
|
//
|
// log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", loginDto.getCode());
|
// WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig);
|
// Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(loginDto.getCode()));
|
// String openid = body.getOpenid();
|
// loginDto.setOpenId(openid);
|
//
|
// try {
|
// Map<String, Object> token = securityUtils.login(username, one, authenticationManager, SecUser.class, 2);
|
//
|
// //保存登录记录
|
// try {
|
// loginRecordService.saveNew((SecurityUserDetails) token.get("userInfo"));
|
// } catch (Exception e) {
|
// log.error("登录记录失败!");
|
// }
|
//
|
// return ApiResult.success(token);
|
// } catch (Exception e) {
|
// ApiResult<Map<String, Object>> failed = ApiResult.failed(new HashMap<>(1));
|
// failed.setCode(0);
|
// failed.setSuccess(false);
|
// failed.setMsg(e.getMessage());
|
// return failed;
|
// }
|
// return ApiResult.success(new HashMap<>());
|
// }
|
|
/**
|
* 登录接口
|
*/
|
// @ApiOperation("短信登录")
|
// @PostMapping(value = "code/login")
|
// public ApiResult<List<SecUser>> loginByCode(@Validated @RequestBody LoginCodeDTO dto) {
|
// // 先检验是否登录
|
// String phone = dto.getPhone();
|
// String code = dto.getCode();
|
// // 校验验证码是否正确
|
// String redisCode = redisAutoTemplate.getStr(dto.getPhone());
|
// Assert.isTrue(StringUtils.hasLength(redisCode), "验证码已过期");
|
// if (!code.equals(redisCode)) {
|
// throw new ServiceException(500, "验证码错误,请重新输入验证码!");
|
// }
|
// try {
|
//// List<SecUser> list = secUserService.list(Wrappers.lambdaQuery(SecUser.class)
|
//// .eq(SecUser::getPhone, phone));
|
//// list = list.stream().filter(o -> !o.getShortName().contains("admin")).collect(Collectors.toList());
|
//// Map<String, Object> token = securityUtils.login(phone, code, authenticationManager, SecurityUserDetails.class, true);
|
// //保存登录记录
|
// return ApiResult.success(new ArrayList<>());
|
// } catch (Exception e) {
|
// ApiResult<List<SecUser>> failed = ApiResult.failed(new ArrayList<>(1));
|
// failed.setCode(0);
|
// failed.setSuccess(false);
|
// failed.setMsg(e.getMessage());
|
// return failed;
|
// }
|
// }
|
|
@ApiOperation("发送验证码")
|
@PostMapping(value = "sendCode")
|
public ApiResult<String> sendCode(@RequestBody VerificationCodeDTO dto) throws ClientException {
|
|
// 账号查询用户
|
SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
|
.eq(SecUser::getAccount, dto.getPhone()));
|
Assert.isTrue(Objects.nonNull(secUser), "该账号不存在");
|
|
// 发送验证码并存储到redis
|
if (StringUtils.hasLength(dto.getPhone())) {
|
if(!loginInfoUtil.checkPhoneExits(dto.getPhone())){
|
throw new ServiceException("无效手机号码");
|
}
|
String code = String.valueOf((int) (Math.random() * 1000000));
|
//TODO 临时验证码,短信未开通前测试用
|
// code = "666666";
|
redisAutoTemplate.setStr("code:"+dto.getPhone(), code);
|
redisAutoTemplate.expire(dto.getPhone(), Constant.REDIS_EXPIRE);
|
// msgUtils.sendSMS(dto.getPhone(), code);
|
|
AliSms aliSms =new AliSms();
|
aliSms.setCode(code);
|
aliSms.setProduct(dto.getPhone());
|
String json = JSONObject.toJSONString(aliSms);
|
aLiSendSms.sendSms(dto.getPhone(), "SMS_58880127", json);
|
|
return ApiResult.success("发送短信验证码成功!15分钟内有效");
|
}
|
return ApiResult.failed(500, "发送短信验证码失败,请确认手机号码!");
|
}
|
|
|
@ApiOperation("发送修改密码验证码")
|
@PostMapping(value = "sendPassCode")
|
public ApiResult<String> sendPassCode(@RequestBody VerificationCodeDTO dto) throws ClientException {
|
|
// 账号查询用户
|
SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
|
.eq(SecUser::getAccount, dto.getPhone()));
|
Assert.isTrue(Objects.nonNull(secUser), "该账号不存在");
|
|
// 发送验证码并存储到redis
|
if (StringUtils.hasLength(dto.getPhone())) {
|
if(!loginInfoUtil.checkPhoneExits(dto.getPhone())){
|
throw new ServiceException("无效手机号码");
|
}
|
String code = String.valueOf((int) (Math.random() * 1000000));
|
//TODO 临时验证码,短信未开通前测试用
|
// code = "666666";
|
redisAutoTemplate.setStr("code:"+dto.getPhone(), code);
|
redisAutoTemplate.expire(dto.getPhone(), Constant.REDIS_EXPIRE);
|
// msgUtils.sendSMS(dto.getPhone(), code);
|
|
AliSms aliSms =new AliSms();
|
aliSms.setCode(code);
|
aliSms.setProduct(dto.getPhone());
|
String json = JSONObject.toJSONString(aliSms);
|
aLiSendSms.sendSms(dto.getPhone(), "SMS_58880123", json);
|
|
return ApiResult.success("发送短信验证码成功!15分钟内有效");
|
}
|
return ApiResult.failed(500, "发送短信验证码失败,请确认手机号码!");
|
}
|
|
|
@OperLoginLog
|
@ApiOperation("短信登录")
|
@PostMapping(value = "code/login")
|
public ApiResult<Map<String, Object>> loginByCode(@Validated @RequestBody LoginCodeDTO dto) {
|
String phone = dto.getPhone();
|
String code = dto.getCode();
|
// 校验验证码是否正确
|
if(!redisAutoTemplate.hasKey("code:"+phone)){
|
throw new ServiceException(500, "验证码错误");
|
}
|
String redisCode = redisAutoTemplate.getStr("code:"+phone);
|
if (!code.equals(redisCode)) {
|
throw new ServiceException(500, "验证码错误");
|
}
|
try {
|
|
SecUser one = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getAccount, phone));
|
if (Objects.isNull(one)){
|
return ApiResult.failed(500, "请输入正确的账号");
|
}
|
if (one.getState()){
|
return ApiResult.failed(500, "该账号已被冻结,请联系管理员");
|
}
|
|
Map<String, Object> token = securityUtils.login(phone, code, authenticationManager, SecurityUserDetails.class, 2);
|
SecurityUserDetails userDetails = loadUserDetailsService.loadUserByUsername(phone);
|
token.put("userInfo", userDetails);
|
return ApiResult.success(token);
|
} catch (Exception e) {
|
ApiResult<Map<String, Object>> failed = ApiResult.failed(new HashMap<>(1));
|
failed.setCode(0);
|
failed.setSuccess(false);
|
failed.setMsg(e.getMessage());
|
return failed;
|
}
|
}
|
|
@ApiOperation("退出登录")
|
@GetMapping("logout")
|
public ApiResult<String> logout() {
|
boolean flag = securityUtils.invalidateToken(WebUtils.request());
|
if (flag) {
|
return ApiResult.success("退出成功");
|
}
|
return ApiResult.success();
|
}
|
|
@OperationLog(operType = "修改", operDesc = "密码修改", operModul = "用户")
|
@ApiOperation("首页密码修改")
|
@PostMapping("/pageResetPassword")
|
public ApiResult<String> pageResetPassword(@Validated @RequestBody ResetPasswordDTO dto) {
|
// 账号查询用户
|
SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
|
.eq(SecUser::getPhone, dto.getPhone()));
|
Assert.isTrue(Objects.nonNull(secUser), "该账号不存在");
|
|
// 校验短信验证码
|
String str = redisAutoTemplate.getStr("code:"+secUser.getPhone());
|
if(!StringUtils.hasLength(str)){
|
return ApiResult.failed("验证码已过期!");
|
}
|
if(!str.equals(dto.getCode())){
|
return ApiResult.failed("验证码错误");
|
}
|
|
// if (StrUtil.isNotBlank(dto.getPassword())) {
|
// // 根据加密算法加密用户输入的密码,然后和数据库中保存的密码进行比较
|
// if (!this.passwordEncoder.matches(dto.getOldPassword(), secUser.getPassword())) {
|
// throw new BadCredentialsException("输入原密码不正确");
|
// }
|
// 修改密码
|
secUser.setPassword(passwordEncoder.encode(dto.getPassword()));
|
// } else {
|
// // 重置密码
|
// secUser.setPassword(passwordEncoder.encode(Constant.DEF_PASSWORD));
|
// }
|
secUserService.updateById(secUser);
|
return ApiResult.success();
|
}
|
@ApiOperation("钉钉登录")
|
@RequestMapping(value = "/dingding", method = RequestMethod.GET)
|
public ApiResult login (@RequestParam("code") String requestAuthCode) throws Exception {
|
|
|
OapiUserGetuserinfoResponse response;
|
|
String accessTokenRequest = DingTalkAccessTokenRequest.getAccessTokenRequest();
|
String access_token = accessTokenRequest;
|
try {
|
|
//
|
|
// 获取用户信息
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/getuserinfo");
|
OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
|
request.setCode(requestAuthCode);
|
request.setHttpMethod("GET");
|
|
response = client.execute(request, access_token);
|
} catch (Exception e) {
|
// TODO Auto-generated catch block
|
e.printStackTrace();
|
return null;
|
}
|
// 查询得到当前用户的userId
|
// 获得到userId之后应用应该处理应用自身的登录会话管理(session),避免后续的业务交互(前端到应用服务端)每次都要重新获取用户身份,提升用户体验
|
String userId = response.getUserid();
|
Map<String, Object> returnMap = new HashMap<String,Object>();
|
returnMap.put("userId", userId);
|
// return ServiceResult.success(returnMap);
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
|
OapiV2UserGetRequest req = new OapiV2UserGetRequest();
|
req.setUserid(userId);
|
OapiV2UserGetResponse rsp = client.execute(req, access_token);
|
System.out.println(rsp.getBody());
|
|
return ApiResult.success();
|
}
|
@Autowired
|
private ALiSendSms aLiSendSms;
|
// @ApiOperation(value = "发送验证码", notes = "发送验证码")
|
// @PostMapping(value = "sendMsg")
|
// public ApiResult<String> sendMsg(@RequestBody VerificationCodeDTO dto) throws Exception {
|
// // 发送验证码并存储到redis
|
// if (StringUtils.hasLength(dto.getPhone())) {
|
// String code = String.valueOf((int) (Math.random() * 1000000));
|
// redisAutoTemplate.setStr(dto.getPhone(), code);
|
// redisAutoTemplate.expire(dto.getPhone(), Constant.REDIS_EXPIRE);
|
// AliSms aliSms =new AliSms();
|
// aliSms.setCode(code);
|
// aliSms.setProduct(dto.getPhone());
|
// String json = JSONObject.toJSONString(aliSms);
|
// aLiSendSms.sendSms(dto.getPhone(), "SMS_58880127", json);
|
// return ApiResult.success("发送短信验证码成功!15分钟内有效");
|
// }
|
// return ApiResult.failed(500, "发送短信验证码失败,请确认手机号码!");
|
// }
|
|
|
|
|
}
|