| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- package com.dk.oauth.service.impl;
- import com.alibaba.fastjson.JSONObject;
- import com.baomidou.mybatisplus.core.metadata.IPage;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.dk.common.infrastructure.constant.Constant;
- import com.dk.common.infrastructure.constant.OauthConstants;
- import com.dk.common.infrastructure.enums.ErrorCodeEnum;
- import com.dk.common.model.response.mst.StaffResponse;
- import com.dk.common.response.ResponseCodeEnum;
- import com.dk.common.response.ResponseResultUtil;
- import com.dk.common.response.ResponseResultVO;
- import com.dk.common.util.DateUtils;
- import com.dk.common.util.HttpUtils;
- import com.dk.oauth.config.WxConfig;
- import com.dk.oauth.dto.AuthAccessTokenDto;
- import com.dk.oauth.entity.*;
- import com.dk.oauth.feign.service.StaffFeign;
- import com.dk.oauth.mapper.AuthAccessTokenMapper;
- import com.dk.oauth.mapper.CompanyMapper;
- import com.dk.oauth.mapper.UserMapper;
- import com.dk.oauth.service.IAuthAccessTokenService;
- import com.dk.oauth.shiro.jwt.JWTGenerator;
- import com.dk.oauth.util.AESSecurityUtil;
- import com.dk.oauth.util.UUID;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
- import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
- import org.apache.shiro.SecurityUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.data.redis.core.StringRedisTemplate;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import javax.annotation.Resource;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.time.LocalDate;
- import java.time.LocalDateTime;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.TimeUnit;
- /**
- * (AuthAccessToken)表服务实现类
- *
- * @author dapeng
- * @since 2022-07-01 09:41:05
- */
- @Slf4j
- @Service("authAccessTokenService")
- public class AuthAccessTokenServiceImpl extends ServiceImpl<AuthAccessTokenMapper, AuthAccessToken> implements IAuthAccessTokenService {
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
- @Resource
- private AuthAccessTokenMapper authAccessTokenMapper;
- @Resource
- private UserMapper userMapper;
- @Resource
- private CompanyMapper companyMapper;
- @Value("${aes-key}")
- private String AESKey;
- @Resource
- private StringRedisTemplate stringRedisTemplate;
- @Autowired
- private WxConfig config;
- @Resource
- private StaffFeign staffFeign;
- /**
- * 分页查询
- *
- * @param
- * @return
- */
- @Override
- public ResponseResultVO pageQuery(AuthAccessTokenDto authAccessTokenDto) {
- if (null == authAccessTokenDto.getPage()) {
- authAccessTokenDto.setPage(new Page(0, 10));
- }
- IPage<AuthAccessTokenDto> authAccessTokenDtos = authAccessTokenMapper.pageQuery(authAccessTokenDto.getPage(), authAccessTokenDto);
- return ResponseResultUtil.success(authAccessTokenDtos);
- }
- /**
- * @desc : 查询用户最新token
- * @author : 洪旭东
- * @date : 2022-08-02 17:30
- */
- public String getCurrentToken(Long userId) {
- return authAccessTokenMapper.getCurrentToken(userId);
- }
- /**
- * @desc : 登录凭证校验
- * @author : 姜永辉
- * @date : 2022/5/12 9:33
- */
- public ResponseResultVO<JSONObject> loginWechat(Map<String, Object> map) {
- ResponseResultVO<JSONObject> res = HttpUtils.get(config.getCode2Session()
- + "appid=" + config.getAppId()
- + "&secret=" + config.getAppSecret()
- + "&js_code=" + map.get("code")
- + "&grant_type=authorization_code");
- if (res.getData() != null && res.getData().get("errcode") != null) {
- return ResponseResultUtil.error(ResponseCodeEnum.OPERATE_FAIL.getCode(),
- res.getData().get("errmsg") == null ? res.getData().getString("errcode")
- : "微信服务器异常:" + res.getData().getString("errmsg"));
- }
- return res;
- }
- /**
- * @desc : 获取token
- * @author : 洪旭东
- * @date : 2024-02-20 14:04
- */
- public ResponseResultVO token(HttpServletRequest request) {
- UserLogin userLogin = userMapper.getByPhone(request.getParameter("phone"));
- if (userLogin == null || (!userLogin.getUserPwd().equals(request.getParameter("password")))) {
- //无用户 或 密码错误
- return ResponseResultUtil.error(ErrorCodeEnum.USER_PASSWORD_ERROR.getCode(), ErrorCodeEnum.USER_PASSWORD_ERROR.getMessage());
- }
- userLogin.checkUserLogin();
- try {
- // 设置应用代码
- userLogin.setAppCode(Constant.AppCode.WEB.getCode());
- return createToken(userLogin);
- } catch (Exception e) {
- log.error("获取accessToken发生异常=", e);
- return ResponseResultUtil.error(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
- }
- }
- /**
- * @desc : 小程序通过微信openid登录
- * @author : 洪旭东
- * @date : 2024-02-20 14:04
- */
- @Transactional(rollbackFor = Exception.class)
- public ResponseResultVO wxToken(UserWxLogin userWxLogin) {
- // todo
- userWxLogin.setUserWxid("1");
- UserLogin userLogin = userMapper.getByWxid(userWxLogin.getUserWxid());
- if (userLogin == null) {
- //无用户
- return ResponseResultUtil.error(ErrorCodeEnum.USER_NOT_EXIST.getCode(), ErrorCodeEnum.USER_NOT_EXIST.getMessage());
- }
- userLogin.checkUserLogin();
- try {
- // 设置应用代码
- userLogin.setAppCode(Constant.AppCode.WEIXIN.getCode());
- return createToken(userLogin);
- } catch (Exception e) {
- log.error("获取accessToken发生异常=", e);
- return ResponseResultUtil.error(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
- }
- }
- /**
- * @desc : 小程序通过微信openid登录--体验的账号
- * @author : 姜永辉
- * @date : 2024-02-20 14:04
- */
- @Transactional(rollbackFor = Exception.class)
- public ResponseResultVO wxFeignExperienceToken(UserWxLogin userWxLogin) {
- UserLogin userLogin = userMapper.getByWxid(userWxLogin.getUserWxid());
- if (userLogin == null) {
- //无用户
- return ResponseResultUtil.error(ErrorCodeEnum.USER_NOT_EXIST.getCode(), ErrorCodeEnum.USER_NOT_EXIST.getMessage());
- }
- try {
- // 设置应用代码
- userLogin.setAppCode(Constant.AppCode.WEIXIN.getCode());
- return createFeignExperienceToken(userLogin);
- } catch (Exception e) {
- log.error("获取accessToken发生异常=", e);
- return ResponseResultUtil.error(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
- }
- }
- /**
- * @desc : 登录验证成功,生成token
- * @author : 姜永辉
- * @date : 2024-02-20 10:31
- */
- private ResponseResultVO<?> createFeignExperienceToken(UserLogin userLogin) throws OAuthSystemException {
- String clientId = "dkic";
- AuthAccessToken authAccessToken = new AuthAccessToken();
- String username = "";
- String userId = "";
- username = userLogin.getUserName();
- userId = String.valueOf(userLogin.getUserId());
- //当前公司
- CompanyResponse company = null;
- String accessToken = "";
- if (userLogin.getCurrentCp() != null) {
- company = companyMapper.getByCpId(userLogin.getCurrentCp());
- if (company != null) {
- JWTGenerator jwtGenerator = new JWTGenerator();
- jwtGenerator.setSalt(username);
- jwtGenerator.setUsername(username);
- jwtGenerator.setUserId(userId);
- jwtGenerator.setClientId(clientId);
- jwtGenerator.setCpId(company.getCpId().toString());
- jwtGenerator.setCpCode(company.getCpCode());
- OAuthIssuerImpl oAuthIssuer = new OAuthIssuerImpl(jwtGenerator);
- accessToken = oAuthIssuer.accessToken();
- log.info("服务器生成的accessToken=" + accessToken);
- // 保存token
- authAccessToken.setId(UUID.uuid32());
- authAccessToken.setClientId(clientId);
- authAccessToken.setTokenId(accessToken);
- authAccessToken.setCreateDate(new Date());
- authAccessToken.setCpId(company.getCpId().toString());
- authAccessToken.setCpCode(company.getCpCode());
- authAccessToken.setTokenExpiredSeconds(OauthConstants.EXPIRES_IN);
- log.info("---->>>SecurityUtils.getSubject().isAuthenticated() = " + SecurityUtils.getSubject().isAuthenticated());
- // endregion
- // region 加密accessToken
- try {
- accessToken = AESSecurityUtil.encrypt(AESKey, accessToken);
- } catch (Exception e) {
- logger.error("sorry,accessToken({}) encode faild!!", accessToken);
- }
- }
- }
- // 默认取体验公司的dktest账号
- Map<String, Object> collectQuery = new HashMap<>();
- collectQuery.put("cpId", userLogin.getCurrentCp());
- collectQuery.put("staffCode", "东科智云-标准版-体验");
- ResponseResultVO<StaffResponse> feignExperience = staffFeign.getFeignExperience(collectQuery);
- StaffResponse s = new StaffResponse();
- log.info("---->>>getFeignExperience = " + feignExperience.toString());
- //如果没有成功返回,状态设置为待审
- if (feignExperience.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
- //无用户
- return ResponseResultUtil.error(ErrorCodeEnum.USER_NOT_EXIST.getCode(), ErrorCodeEnum.USER_NOT_EXIST.getMessage());
- } else {
- s = feignExperience.getData();
- }
- UserLoginSuccess userLoginSuccess = new UserLoginSuccess()
- .setByUserLogin(userLogin)
- .setAccessToken(accessToken)
- .setCompany(company)
- .setStaffResponse(s)
- // .setMenuList(userMapper.getMenuByUser(userLogin.getAppCode(),userId,company.getCpId(),"zh_CN"))
- ;
- return ResponseResultUtil.success(userLoginSuccess);
- }
- /**
- * @desc : 注册
- * @author : 洪旭东
- * @date : 2024-02-20 13:55
- */
- @Transactional(rollbackFor = Exception.class)
- public ResponseResultVO<?> register(UserWxLogin userWxLogin) {
- UserLogin userLogin = userMapper.getByWxid(userWxLogin.getUserWxid());
- //通过openid查到用户,但手机号为空
- if (userLogin != null && userLogin.getUserPhone() == null) {
- //将其他微信用户的相同电话清空
- userMapper.cleanPhone(userWxLogin.getUserPhone());
- //更新当前手机号
- userMapper.updatePhone(userLogin.getUserId(), userWxLogin.getUserPhone());
- }
- if (userLogin == null) {
- //openid没查到,用手机号再查一次
- userLogin = userMapper.getByPhone(userWxLogin.getUserPhone());
- } else if (userLogin.getUserWxid() == null) {
- //通过手机号查到了用户,但是openid是空,更新上当前的openid
- userMapper.updateWxid(userLogin.getUserId(), userWxLogin.getUserWxid());
- }
- //用户无法通过openid或手机号查到 或 通过手机号查到了,但openid不同
- if (userLogin == null || !userWxLogin.getUserWxid().equals(userLogin.getUserWxid())) {
- //将其他微信用户的相同电话清空
- userMapper.cleanPhone(userWxLogin.getUserPhone());
- //注册
- userMapper.insert(userWxLogin);
- userLogin = userMapper.getByWxid(userWxLogin.getUserWxid());
- }
- userLogin.checkUserLogin();
- try {
- return createToken(userLogin);
- } catch (Exception e) {
- log.error("获取accessToken发生异常=", e);
- return ResponseResultUtil.error(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
- }
- }
- /**
- * @desc : 验证当前扫码登录是否匹配到openid
- * @author : 洪旭东
- * @date : 2024-02-20 14:04
- */
- public ResponseResultVO<?> checkLoginOpenId(String uuid) {
- String openId = stringRedisTemplate.opsForValue().get(Constant.RedisConstant.REDIS_LOGIN_UUID.getName() + uuid);
- if (openId != null && !"".equals(openId)) {
- UserLogin userLogin = userMapper.getByWxid(openId);
- if (userLogin == null) {
- stringRedisTemplate.opsForValue().set(Constant.RedisConstant.REDIS_LOGIN_UUID.getName() + uuid, "", 5, TimeUnit.MINUTES);
- //无用户
- return ResponseResultUtil.error(ErrorCodeEnum.USER_NOT_EXIST.getCode(), ErrorCodeEnum.USER_NOT_EXIST.getMessage());
- }
- userLogin.checkUserLogin();
- try {
- return createToken(userLogin);
- } catch (OAuthSystemException e) {
- e.printStackTrace();
- log.error("获取accessToken发生异常=", e);
- return ResponseResultUtil.error(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
- }
- } else {
- return ResponseResultUtil.error(ResponseCodeEnum.NO_LOGIN);
- }
- }
- /**
- * @desc : 登录验证成功,生成token
- * @author : 洪旭东
- * @date : 2024-02-20 10:31
- */
- private ResponseResultVO<?> createToken(UserLogin userLogin) throws OAuthSystemException {
- String clientId = "dkic";
- AuthAccessToken authAccessToken = new AuthAccessToken();
- // region 开始生成Access Token
- String username = "";
- String userId = "";
- username = userLogin.getUserName();
- userId = String.valueOf(userLogin.getUserId());
- // endregion
- //当前公司
- CompanyResponse company = null;
- String accessToken = "";
- if (userLogin.getCurrentCp() != null) {
- company = companyMapper.getByCpId(userLogin.getCurrentCp());
- if (company != null) {
- JWTGenerator jwtGenerator = new JWTGenerator();
- jwtGenerator.setSalt(username);
- jwtGenerator.setUsername(username);
- jwtGenerator.setUserId(userId);
- jwtGenerator.setClientId(clientId);
- jwtGenerator.setCpId(company.getCpId().toString());
- jwtGenerator.setCpCode(company.getCpCode());
- jwtGenerator.setAppCode(userLogin.getAppCode());
- OAuthIssuerImpl oAuthIssuer = new OAuthIssuerImpl(jwtGenerator);
- accessToken = oAuthIssuer.accessToken();
- log.info("服务器生成的accessToken=" + accessToken);
- // 保存token
- authAccessToken.setId(UUID.uuid32());
- authAccessToken.setClientId(clientId);
- authAccessToken.setTokenId(accessToken);
- authAccessToken.setCreateDate(new Date());
- authAccessToken.setUserId(userId);
- authAccessToken.setCpId(company.getCpId().toString());
- authAccessToken.setCpCode(company.getCpCode());
- authAccessToken.setAppCode(userLogin.getAppCode());
- authAccessToken.setTokenExpiredSeconds(OauthConstants.EXPIRES_IN);
- log.info("---->>>SecurityUtils.getSubject().isAuthenticated() = " + SecurityUtils.getSubject().isAuthenticated());
- // endregion
- // region 加密accessToken
- try {
- accessToken = AESSecurityUtil.encrypt(AESKey, accessToken);
- // 往redis记录缓存
- Map<String,Object> ul = new HashMap<>();
- ul.put("accessToken",accessToken);
- ul.put("opUpdateTime",LocalDateTime.now());
- stringRedisTemplate.opsForValue().set(Constant.RedisConstant.REDIS_USER_LOGIN.getName() + '_' + userId + '_' + userLogin.getAppCode(), JSONObject.toJSONString(ul));
- } catch (Exception e) {
- logger.error("sorry,accessToken({}) encode faild!!", accessToken);
- }
- }
- }
- UserLoginSuccess userLoginSuccess = new UserLoginSuccess()
- .setByUserLogin(userLogin)
- .setAccessToken(accessToken)
- .setCompany(company);
- return ResponseResultUtil.success(userLoginSuccess);
- }
- /**
- * @desc : 生成微信临时二维码
- * @author : 洪旭东
- * @date : 2024-02-20 17:00
- */
- public ResponseResultVO<?> getQrCode(String uuid) {
- //获取access token
- String accessToken = stringRedisTemplate.opsForValue().get(Constant.RedisConstant.REDIS_WECHAT_ACCESS_TOKEN.getName());
- if (accessToken == null) {
- ResponseResultVO<JSONObject> tokenRes = HttpUtils.get(config.getAccessToken() + "appid=" + config.getOffiAccountAppId() + "&secret=" + config.getOffiAccountAppSecret());
- if (tokenRes.getCode() == ResponseCodeEnum.SUCCESS.getCode()) {
- stringRedisTemplate.opsForValue().set(Constant.RedisConstant.REDIS_WECHAT_ACCESS_TOKEN.getName(), tokenRes.getData().getString("access_token"), 5, TimeUnit.MINUTES);
- accessToken = tokenRes.getData().getString("access_token");
- } else {
- return tokenRes;
- }
- }
- //生成临时二维码
- String ticket;
- JSONObject json = new JSONObject();
- //有效期30天,最大可设置30天
- json.put("expire_seconds", 2592000);
- json.put("action_name", "QR_STR_SCENE");
- JSONObject scene = new JSONObject();
- scene.put("scene_str", "dkic-scan-login-" + uuid);
- JSONObject actionInfo = new JSONObject();
- actionInfo.put("scene", scene);
- json.put("action_info", actionInfo);
- ResponseResultVO<JSONObject> ticketRes = HttpUtils.post(config.getQrcodeCreate() + accessToken, json);
- if (ticketRes.getCode() == ResponseCodeEnum.SUCCESS.getCode()) {
- ticket = ticketRes.getData().getString("ticket");
- } else {
- return ticketRes;
- }
- stringRedisTemplate.opsForValue().set(Constant.RedisConstant.REDIS_LOGIN_UUID.getName() + uuid, "", 5, TimeUnit.MINUTES);
- return ResponseResultUtil.success(config.getShowQrCode() + ticket);
- }
- /**
- * @desc : 生成微信小程序二维码
- * @author : 姜永辉
- * @date : 2024-02-20 17:00
- */
- public ResponseResultVO<?> getWxQrCode(Map<String, Object> map) {
- System.out.println("getWxQrCode:" + map);
- //获取access token
- String accessToken = stringRedisTemplate.opsForValue().get(Constant.RedisConstant.REDIS_WECHAT_QRCODE_ACCESS_TOKEN.getName());
- if (accessToken == null) {
- ResponseResultVO<JSONObject> tokenRes = HttpUtils.get(config.getAccessToken()
- + "appid=" + config.getAppId()
- + "&secret=" + config.getAppSecret());
- if (tokenRes.getCode() == ResponseCodeEnum.SUCCESS.getCode()) {
- stringRedisTemplate.opsForValue().set(Constant.RedisConstant.REDIS_WECHAT_QRCODE_ACCESS_TOKEN.getName(),
- tokenRes.getData().getString("access_token"), 5, TimeUnit.MINUTES);
- accessToken = tokenRes.getData().getString("access_token");
- } else {
- return tokenRes;
- }
- }
- //二维码参数
- Map<String, Object> param = new HashMap<>();
- param.put("page", "pages/welcome/welcome");
- param.put("scene", "s=" + map.get("openid"));
- param.put("check_path", false);
- //生成二维码接口地址
- String url = config.getUnlimitedQRCode() + accessToken;
- //文件名称
- String fileName = java.util.UUID.randomUUID().toString() + ".png";
- //文件相对路径 - 返回
- String relativePath = "/qr_code/" + fileName;
- //文件绝对路径 - 写
- String absolutelyPath = this.createDirByPath("qr_code") + fileName;
- ResponseResultVO<String> responseResultVO = HttpUtils.postReturnFile(url, param, absolutelyPath);
- if (responseResultVO.getCode() == ResponseCodeEnum.SUCCESS.getCode()) {
- return ResponseResultUtil.success(relativePath);
- } else {
- return responseResultVO;
- }
- }
- private String createDirByPath(String type) {
- /**
- * @date_time 2020-07-31 09:42
- * @author H_x_d
- * @description 根据类型创建目录文件夹
- * @param [type]
- * @return java.lang.String
- */
- String path = type + "/" + DateUtils.formatNow("yyyy-MM-dd") + "/";
- String base = config.getUploadPath();
- File baseDir = new File(base);
- if (!baseDir.exists()) {
- baseDir.mkdir();
- }
- String[] paths = path.split("/");
- for (int i = 0; i < paths.length; i++) {
- base = base + "/" + paths[i];
- File dir = new File(base);
- if (!dir.exists()) {
- dir.mkdir();
- }
- }
- return base + "/";
- }
- }
|