mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	初步完成微信公众号登录
This commit is contained in:
		| @@ -1,55 +0,0 @@ | ||||
| package cn.iocoder.yudao.userserver.modules.member.enums.social; | ||||
|  | ||||
| import cn.hutool.core.collection.ListUtil; | ||||
| import cn.hutool.core.util.ArrayUtil; | ||||
| import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Getter; | ||||
|  | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 社交平台的类型枚举 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @Getter | ||||
| @AllArgsConstructor | ||||
| public enum SysSocialTypeEnum implements IntArrayValuable { | ||||
|  | ||||
|     GITEE(10, "GITEE"), // https://gitee.com/api/v5/oauth_doc#/ | ||||
|     DINGTALK(20, "DINGTALK"), // https://developers.dingtalk.com/document/app/obtain-identity-credentials | ||||
|     WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"), // https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html | ||||
|     ; | ||||
|  | ||||
|     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysSocialTypeEnum::getType).toArray(); | ||||
|  | ||||
|     public static final List<Integer> WECHAT_ALL = ListUtil.toList(WECHAT_ENTERPRISE.type); | ||||
|  | ||||
|     /** | ||||
|      * 类型 | ||||
|      */ | ||||
|     private final Integer type; | ||||
|     /** | ||||
|      * 类型的标识 | ||||
|      */ | ||||
|     private final String source; | ||||
|  | ||||
|     @Override | ||||
|     public int[] array() { | ||||
|         return ARRAYS; | ||||
|     } | ||||
|  | ||||
|     public static SysSocialTypeEnum valueOfType(Integer type) { | ||||
|         return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); | ||||
|     } | ||||
|  | ||||
|     public static List<Integer> getRelationTypes(Integer type) { | ||||
|         if (WECHAT_ALL.contains(type)) { | ||||
|             return WECHAT_ALL; | ||||
|         } | ||||
|         return ListUtil.toList(type); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,9 +1,13 @@ | ||||
| package cn.iocoder.yudao.userserver.modules.system.controller.auth; | ||||
|  | ||||
| import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; | ||||
| import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||
| import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | ||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; | ||||
| import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; | ||||
| import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; | ||||
| import com.alibaba.fastjson.JSON; | ||||
| import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiImplicitParam; | ||||
| import io.swagger.annotations.ApiImplicitParams; | ||||
| @@ -13,11 +17,13 @@ import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.validation.Valid; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||
| import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | ||||
| import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent; | ||||
| import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||||
|  | ||||
| @Api(tags = "认证") | ||||
| @RestController | ||||
| @@ -30,6 +36,9 @@ public class SysAuthController { | ||||
|     private SysAuthService authService; | ||||
|     @Resource | ||||
|     private SysSmsCodeService smsCodeService; | ||||
|     @Resource | ||||
|     private SysSocialService socialService; | ||||
|  | ||||
|  | ||||
|     @PostMapping("/login") | ||||
|     @ApiOperation("使用手机 + 密码登录") | ||||
| @@ -70,42 +79,47 @@ public class SysAuthController { | ||||
|     }) | ||||
|     public CommonResult<String> socialAuthRedirect(@RequestParam("type") Integer type, | ||||
|                                                    @RequestParam("redirectUri") String redirectUri) { | ||||
| //        return CommonResult.success(socialService.getAuthorizeUrl(type, redirectUri)); | ||||
|         return null; | ||||
|         return CommonResult.success(socialService.getAuthorizeUrl(type, redirectUri)); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/social-login-get") | ||||
|     @ApiOperation("社交登录,使用 code 授权码") | ||||
|     @ResponseBody | ||||
|     @Deprecated | ||||
|     public CommonResult<MbrAuthSocialLoginReqVO> socialLoginGet(HttpServletRequest request,String code,String state) { | ||||
|         // 返回结果 | ||||
|         MbrAuthSocialLoginReqVO reqVO = MbrAuthSocialLoginReqVO.builder().state(state).code(code).build(); | ||||
|         reqVO.setType(12); | ||||
|         System.out.println(JSON.toJSON(reqVO)); | ||||
|         return success(reqVO); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/social-login") | ||||
|     @ApiOperation("社交登录,使用 code 授权码") | ||||
|         public CommonResult<SysAuthLoginRespVO> socialLogin(@RequestBody @Valid MbrAuthSocialLoginReqVO reqVO) { | ||||
| //        String token = authService.socialLogin(reqVO, getClientIP(), getUserAgent()); | ||||
| //        // 返回结果 | ||||
| //        return success(MbrAuthLoginRespVO.builder().token(token).build()); | ||||
|         return null; | ||||
|     public CommonResult<SysAuthLoginRespVO> socialLogin(@RequestBody @Valid MbrAuthSocialLoginReqVO reqVO) { | ||||
|         String token = authService.socialLogin(reqVO, getClientIP(), getUserAgent()); | ||||
|         return success(SysAuthLoginRespVO.builder().token(token).build()); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/social-login2") | ||||
|     @ApiOperation("社交登录,使用 code 授权码 + 账号密码") | ||||
|     public CommonResult<SysAuthLoginRespVO> socialLogin2(@RequestBody @Valid MbrAuthSocialLogin2ReqVO reqVO) { | ||||
| //        String token = authService.socialLogin2(reqVO, getClientIP(), getUserAgent()); | ||||
| //        // 返回结果 | ||||
| //        return success(MbrAuthLoginRespVO.builder().token(token).build()); | ||||
|         return null; | ||||
|         String token = authService.socialLogin2(reqVO, getClientIP(), getUserAgent()); | ||||
|         return success(SysAuthLoginRespVO.builder().token(token).build()); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/social-bind") | ||||
|     @ApiOperation("社交绑定,使用 code 授权码") | ||||
|     public CommonResult<Boolean> socialBind(@RequestBody @Valid MbrAuthSocialBindReqVO reqVO) { | ||||
| //        authService.socialBind(getLoginUserId(), reqVO); | ||||
| //        return CommonResult.success(true); | ||||
|         return null; | ||||
|         authService.socialBind(getLoginUserId(), reqVO); | ||||
|         return CommonResult.success(true); | ||||
|     } | ||||
|  | ||||
|     @DeleteMapping("/social-unbind") | ||||
|     @ApiOperation("取消社交绑定") | ||||
|     public CommonResult<Boolean> socialUnbind(@RequestBody MbrAuthSocialUnbindReqVO reqVO) { | ||||
| //        socialService.unbindSocialUser(getLoginUserId(), reqVO.getType(), reqVO.getUnionId()); | ||||
| //        return CommonResult.success(true); | ||||
|         return null; | ||||
|         socialService.unbindSocialUser(getLoginUserId(), reqVO.getType(), reqVO.getUnionId(), UserTypeEnum.MEMBER); | ||||
|         return CommonResult.success(true); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; | ||||
|  | ||||
| import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.validation.InEnum; | ||||
| import cn.iocoder.yudao.userserver.modules.member.enums.social.SysSocialTypeEnum; | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.AllArgsConstructor; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; | ||||
|  | ||||
| import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.validation.InEnum; | ||||
| import cn.iocoder.yudao.userserver.modules.member.enums.social.SysSocialTypeEnum; | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.AllArgsConstructor; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; | ||||
|  | ||||
| import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.validation.InEnum; | ||||
| import cn.iocoder.yudao.userserver.modules.member.enums.social.SysSocialTypeEnum; | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.AllArgsConstructor; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; | ||||
|  | ||||
| import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.validation.InEnum; | ||||
| import cn.iocoder.yudao.userserver.modules.member.enums.social.SysSocialTypeEnum; | ||||
| import io.swagger.annotations.ApiModel; | ||||
| import io.swagger.annotations.ApiModelProperty; | ||||
| import lombok.AllArgsConstructor; | ||||
|   | ||||
| @@ -14,6 +14,7 @@ public interface SysErrorCodeConstants { | ||||
|     ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1005000001, "登录失败,账号被禁用"); | ||||
|     ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1005000002, "登录失败"); // 登录失败的兜底,未知原因 | ||||
|     ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1005000003, "Token 已经过期"); | ||||
|     ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1005000004, "未绑定账号,需要进行绑定"); | ||||
|  | ||||
|     // ========== SMS CODE 模块 1005001000 ========== | ||||
|     ErrorCode USER_SMS_CODE_NOT_FOUND = new ErrorCode(1005001000, "验证码不存在"); | ||||
| @@ -22,4 +23,7 @@ public interface SysErrorCodeConstants { | ||||
|     ErrorCode USER_SMS_CODE_NOT_CORRECT = new ErrorCode(1005001003, "验证码不正确"); | ||||
|     ErrorCode USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1005001004, "超过每日短信发送数量"); | ||||
|     ErrorCode USER_SMS_CODE_SEND_TOO_FAST = new ErrorCode(1005001005, "短信发送过于频率"); | ||||
|  | ||||
|     // ========== 用户模块 1005002000 ========== | ||||
|     ErrorCode USER_NOT_EXISTS = new ErrorCode(1005002001, "用户不存在"); | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| package cn.iocoder.yudao.userserver.modules.system.service.auth; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; | ||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthLoginReqVO; | ||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSmsLoginReqVO; | ||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; | ||||
|  | ||||
| import javax.validation.Valid; | ||||
|  | ||||
| @@ -35,4 +34,33 @@ public interface SysAuthService extends SecurityAuthFrameworkService { | ||||
|      */ | ||||
|     String smsLogin(@Valid SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 社交登录,使用 code 授权码 | ||||
|      * | ||||
|      * @param reqVO 登录信息 | ||||
|      * @param userIp 用户 IP | ||||
|      * @param userAgent 用户 UA | ||||
|      * @return 身份令牌,使用 JWT 方式 | ||||
|      */ | ||||
|     String socialLogin(@Valid MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent); | ||||
|  | ||||
|     /** | ||||
|      * 社交登录,使用 code 授权码 + 账号密码 | ||||
|      * | ||||
|      * @param reqVO 登录信息 | ||||
|      * @param userIp 用户 IP | ||||
|      * @param userAgent 用户 UA | ||||
|      * @return 身份令牌,使用 JWT 方式 | ||||
|      */ | ||||
|     String socialLogin2(@Valid MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent); | ||||
|  | ||||
|     /** | ||||
|      * 社交绑定,使用 code 授权码 | ||||
|      * | ||||
|      * @param userId 用户编号 | ||||
|      * @param reqVO 绑定信息 | ||||
|      */ | ||||
|     void socialBind(Long userId, @Valid MbrAuthSocialBindReqVO reqVO); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,25 +1,29 @@ | ||||
| package cn.iocoder.yudao.userserver.modules.system.service.auth.impl; | ||||
|  | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.lang.Assert; | ||||
| import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; | ||||
| import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO; | ||||
| import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; | ||||
| import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginLogTypeEnum; | ||||
| import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginResultEnum; | ||||
| import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; | ||||
| import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; | ||||
| import cn.iocoder.yudao.coreservice.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; | ||||
| import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||||
| import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; | ||||
| import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | ||||
| import cn.iocoder.yudao.framework.security.core.LoginUser; | ||||
| import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; | ||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthLoginReqVO; | ||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.SysAuthSmsLoginReqVO; | ||||
| import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; | ||||
| import cn.iocoder.yudao.userserver.modules.system.convert.auth.SysAuthConvert; | ||||
| import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; | ||||
| import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; | ||||
| import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import me.zhyd.oauth.model.AuthUser; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.security.authentication.AuthenticationManager; | ||||
| import org.springframework.security.authentication.BadCredentialsException; | ||||
| @@ -33,6 +37,8 @@ import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import javax.validation.Valid; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||
| @@ -59,6 +65,9 @@ public class SysAuthServiceImpl implements SysAuthService { | ||||
|     private SysLoginLogCoreService loginLogCoreService; | ||||
|     @Resource | ||||
|     private SysUserSessionCoreService userSessionCoreService; | ||||
|     @Resource | ||||
|     private SysSocialService socialService; | ||||
|     private static final UserTypeEnum userTypeEnum = UserTypeEnum.MEMBER; | ||||
|  | ||||
|     @Override | ||||
|     public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { | ||||
| @@ -99,6 +108,65 @@ public class SysAuthServiceImpl implements SysAuthService { | ||||
|         return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String socialLogin(MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent) { | ||||
|         // 使用 code 授权码,进行登录 | ||||
|         AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); | ||||
|         org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); | ||||
|  | ||||
|         // 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错 | ||||
|         String unionId = socialService.getAuthUserUnionId(authUser); | ||||
|         List<SysSocialUserDO> socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, userTypeEnum); | ||||
|         if (CollUtil.isEmpty(socialUsers)) { | ||||
|             throw exception(AUTH_THIRD_LOGIN_NOT_BIND); | ||||
|         } | ||||
|  | ||||
|         // 自动登录 | ||||
|         MbrUserDO user = userService.getUser(socialUsers.get(0).getUserId()); | ||||
|         if (user == null) { | ||||
|             throw exception(USER_NOT_EXISTS); | ||||
|         } | ||||
|         this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_SOCIAL, SysLoginResultEnum.SUCCESS); | ||||
|  | ||||
|         // 创建 LoginUser 对象 | ||||
|         LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); | ||||
|         // TODO 芋艿:需要改造下,增加各种登录方式 | ||||
| //        loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 | ||||
|  | ||||
|         // 绑定社交用户(更新) | ||||
|         socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, userTypeEnum); | ||||
|  | ||||
|         // 缓存登录用户到 Redis 中,返回 sessionId 编号 | ||||
|         return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String socialLogin2(MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent) { | ||||
|         // 使用 code 授权码,进行登录 | ||||
|         AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); | ||||
|         org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); | ||||
|  | ||||
|         // 使用账号密码,进行登录。 | ||||
|         LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword()); | ||||
| //        loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 | ||||
|  | ||||
|         // 绑定社交用户(新增) | ||||
|         socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, userTypeEnum); | ||||
|  | ||||
|         // 缓存登录用户到 Redis 中,返回 sessionId 编号 | ||||
|         return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void socialBind(Long userId, MbrAuthSocialBindReqVO reqVO) { | ||||
|         // 使用 code 授权码,进行登录 | ||||
|         AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); | ||||
|         org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); | ||||
|  | ||||
|         // 绑定社交用户(新增) | ||||
|         socialService.bindSocialUser(userId, reqVO.getType(), authUser, userTypeEnum); | ||||
|     } | ||||
|  | ||||
|     private LoginUser login0(String username, String password) { | ||||
|         final SysLoginLogTypeEnum logTypeEnum = SysLoginLogTypeEnum.LOGIN_USERNAME; | ||||
|         // 用户验证 | ||||
| @@ -207,7 +275,7 @@ public class SysAuthServiceImpl implements SysAuthService { | ||||
|         reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); | ||||
|         reqDTO.setTraceId(TracerUtils.getTraceId()); | ||||
|         reqDTO.setUserId(userId); | ||||
|         reqDTO.setUserType(UserTypeEnum.MEMBER.getValue()); | ||||
|         reqDTO.setUserType(userTypeEnum.getValue()); | ||||
|         reqDTO.setUsername(username); | ||||
|         reqDTO.setUserAgent(ServletUtils.getUserAgent()); | ||||
|         reqDTO.setUserIp(ServletUtils.getClientIP()); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 timfruit
					timfruit