From 7ea8d1c6da749da69516f47593ae47546a0d3d4c Mon Sep 17 00:00:00 2001
From: xuhy <3313886187@qq.com>
Date: 星期一, 16 十二月 2024 11:36:46 +0800
Subject: [PATCH] 微信登陆

---
 applet/src/main/java/com/jilongda/applet/controller/LoginController.java |  449 ++++---------------------------------------------------
 1 files changed, 34 insertions(+), 415 deletions(-)

diff --git a/applet/src/main/java/com/jilongda/applet/controller/LoginController.java b/applet/src/main/java/com/jilongda/applet/controller/LoginController.java
index f88cabb..a3f06ce 100644
--- a/applet/src/main/java/com/jilongda/applet/controller/LoginController.java
+++ b/applet/src/main/java/com/jilongda/applet/controller/LoginController.java
@@ -1,30 +1,15 @@
 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.applet.model.TAppUser;
+import com.jilongda.applet.service.TAppUserService;
+import com.jilongda.applet.wx.body.resp.Code2SessionRespBody;
+import com.jilongda.applet.wx.body.resq.Code2SessionResqBody;
+import com.jilongda.applet.wx.pojo.AppletUserDecodeData;
+import com.jilongda.applet.wx.pojo.AppletUserEncrypteData;
+import com.jilongda.applet.wx.utils.WeixinProperties;
+import com.jilongda.applet.wx.utils.WxAppletTools;
+import com.jilongda.applet.wx.utils.WxUtils;
 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;
@@ -33,16 +18,11 @@
 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 org.springframework.web.client.RestTemplate;
 
-import java.util.HashMap;
 import java.util.Map;
-import java.util.Objects;
 
 /**
  * <p>
@@ -57,303 +37,35 @@
 @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;
+    private SecurityUtils securityUtils;
     @Autowired
-    private PasswordEncoder passwordEncoder;
-
+    private AuthenticationManager authenticationManager;
     @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;
-    }
+    private RedisAutoTemplate redisAutoTemplate;
+    @Autowired
+    private TAppUserService appUserService;
+    @Autowired
+    private WeixinProperties wxConfig;
+    @Autowired
+    private RestTemplate wxRestTemplate;
 
-//    @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;
+    @ApiOperation(value = "通过code获得openid,获取用户信息",tags = {"微信小程序登录"})
+    @PostMapping("/openIdByJsCode")
+    public ApiResult<Map<String, Object>> openIdByJsCode(@RequestBody AppletUserEncrypteData data) {
+        log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", data.getCode());
+        WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisAutoTemplate);
+        Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(data.getCode()));
+        String openid = body.getOpenid();
+        String sessionKey = body.getSessionKey();
+        if(!StringUtils.hasLength(data.getEncryptedData()) || !StringUtils.hasLength(data.getIv())){
+            return ApiResult.failed("已拒绝授权",null);
         }
-    }
-
-    /**
-     * 登录接口
-     */
-//    @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;
-        }
+        AppletUserDecodeData appletUserDecodeData = WxUtils.encryptedData(data.getEncryptedData(), sessionKey,  data.getIv());
+        appletUserDecodeData.setOpenId(openid);
+        appUserService.wxLogin(appletUserDecodeData);
+        Map<String, Object> tokenInfos = securityUtils.login(null, null, authenticationManager, TAppUser.class, 3);
+        return ApiResult.success(tokenInfos);
     }
 
     @ApiOperation("退出登录")
@@ -365,99 +77,6 @@
         }
         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, "发送短信验证码失败,请确认手机号码!");
-//    }
 
 
 

--
Gitblit v1.7.1