Commit e05d90590ef2731a81568b2a11b0aa097c23dbdf
1 parent
a56b4a7c
接入 dingtalk 钉钉的三方登陆,流程未接入
Showing
15 changed files
with
342 additions
and
102 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.system.controller.auth; |
| 2 | 2 | |
| 3 | -import cn.hutool.core.net.url.UrlBuilder; | |
| 4 | -import cn.hutool.http.HttpUtil; | |
| 5 | 3 | import cn.hutool.json.JSONUtil; |
| 6 | -import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | |
| 7 | -import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysUserSessionService; | |
| 8 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 9 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 10 | -import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | |
| 11 | -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | |
| 12 | -import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; | |
| 13 | -import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginRespVO; | |
| 14 | -import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO; | |
| 15 | -import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.*; | |
| 16 | 5 | import cn.iocoder.yudao.adminserver.modules.system.convert.auth.SysAuthConvert; |
| 17 | 6 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysMenuDO; |
| 18 | 7 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysRoleDO; |
| 19 | 8 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; |
| 20 | 9 | import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuTypeEnum; |
| 10 | +import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | |
| 21 | 11 | import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysAuthService; |
| 22 | 12 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; |
| 23 | 13 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService; |
| 24 | 14 | import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; |
| 15 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 16 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 25 | 17 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; |
| 26 | -import com.aliyuncs.CommonResponse; | |
| 18 | +import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | |
| 19 | +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | |
| 27 | 20 | import com.xkcoding.justauth.AuthRequestFactory; |
| 28 | 21 | import io.swagger.annotations.Api; |
| 29 | 22 | import io.swagger.annotations.ApiImplicitParam; |
| ... | ... | @@ -35,26 +28,18 @@ import me.zhyd.oauth.model.AuthResponse; |
| 35 | 28 | import me.zhyd.oauth.model.AuthUser; |
| 36 | 29 | import me.zhyd.oauth.request.AuthRequest; |
| 37 | 30 | import me.zhyd.oauth.utils.AuthStateUtils; |
| 38 | -import org.apache.commons.lang.StringUtils; | |
| 39 | -import org.quartz.SimpleTrigger; | |
| 40 | 31 | import org.springframework.validation.annotation.Validated; |
| 41 | 32 | import org.springframework.web.bind.annotation.*; |
| 42 | -import org.springframework.web.multipart.MultipartFile; | |
| 43 | -import org.springframework.web.util.UriBuilder; | |
| 44 | 33 | |
| 45 | 34 | import javax.annotation.Resource; |
| 46 | -import javax.servlet.http.HttpServletResponse; | |
| 47 | 35 | import javax.validation.Valid; |
| 48 | -import java.io.IOException; | |
| 49 | -import java.net.URL; | |
| 50 | -import java.nio.charset.Charset; | |
| 51 | 36 | import java.util.List; |
| 52 | 37 | |
| 53 | 38 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 54 | -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 55 | -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserRoleIds; | |
| 56 | 39 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |
| 57 | 40 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent; |
| 41 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 42 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserRoleIds; | |
| 58 | 43 | |
| 59 | 44 | @Api(tags = "认证") |
| 60 | 45 | @RestController |
| ... | ... | @@ -71,8 +56,6 @@ public class SysAuthController { |
| 71 | 56 | private SysRoleService roleService; |
| 72 | 57 | @Resource |
| 73 | 58 | private SysPermissionService permissionService; |
| 74 | - @Resource | |
| 75 | - private SysUserSessionService sysUserSessionService; | |
| 76 | 59 | |
| 77 | 60 | @Resource |
| 78 | 61 | private AuthRequestFactory authRequestFactory; |
| ... | ... | @@ -86,42 +69,6 @@ public class SysAuthController { |
| 86 | 69 | return success(SysAuthLoginRespVO.builder().token(token).build()); |
| 87 | 70 | } |
| 88 | 71 | |
| 89 | - @GetMapping("/third-login-redirect") | |
| 90 | - @ApiOperation("三方登陆的跳转") | |
| 91 | - @ApiImplicitParams({ | |
| 92 | - @ApiImplicitParam(name = "type", value = "三方类型", required = true, dataTypeClass = Integer.class), | |
| 93 | - @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class) | |
| 94 | - }) | |
| 95 | - public CommonResult<String> login(@RequestParam("type") Integer type, | |
| 96 | - @RequestParam("redirectUri") String redirectUri) throws IOException { | |
| 97 | - // 获得对应的 AuthRequest 实现 | |
| 98 | - AuthRequest authRequest = authRequestFactory.get(SysUserSocialTypeEnum.valueOfType(type).getSource()); | |
| 99 | - // 生成跳转地址 | |
| 100 | - String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); | |
| 101 | - authorizeUri = HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); | |
| 102 | -// authorizeUri = UrlBuilder.fromBaseUrl(authorizeUri).queryParam("redirect_uri", redirectUri).build(); | |
| 103 | - return CommonResult.success(authorizeUri); | |
| 104 | - } | |
| 105 | - | |
| 106 | - @RequestMapping("/{type}/callback") | |
| 107 | - public AuthResponse login(@PathVariable String type, AuthCallback callback) { | |
| 108 | - AuthRequest authRequest = authRequestFactory.get(type); | |
| 109 | - AuthResponse<AuthUser> response = authRequest.login(callback); | |
| 110 | - log.info("【response】= {}", JSONUtil.toJsonStr(response)); | |
| 111 | - return response; | |
| 112 | - } | |
| 113 | - | |
| 114 | -// @RequestMapping("/auth2/login/{oauthType}") | |
| 115 | -// @ApiOperation("第三方登录") | |
| 116 | -// @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | |
| 117 | -// public CommonResult<SysAuthLoginRespVO> login(@PathVariable String oauthType) { | |
| 118 | -// Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | |
| 119 | -// //TODO NPE | |
| 120 | -// String token = sysUserSessionService.getSessionId(authentication.getName()); | |
| 121 | -// // 返回结果 | |
| 122 | -// return success(SysAuthLoginRespVO.builder().token(token).build()); | |
| 123 | -// } | |
| 124 | - | |
| 125 | 72 | @GetMapping("/get-permission-info") |
| 126 | 73 | @ApiOperation("获取登陆用户的权限信息") |
| 127 | 74 | public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() { |
| ... | ... | @@ -153,4 +100,38 @@ public class SysAuthController { |
| 153 | 100 | return success(SysAuthConvert.INSTANCE.buildMenuTree(menuList)); |
| 154 | 101 | } |
| 155 | 102 | |
| 103 | + // ========== 三方登陆相关 ========== | |
| 104 | + | |
| 105 | + @GetMapping("/third-login-redirect") | |
| 106 | + @ApiOperation("三方登陆的跳转") | |
| 107 | + @ApiImplicitParams({ | |
| 108 | + @ApiImplicitParam(name = "type", value = "三方类型", required = true, dataTypeClass = Integer.class), | |
| 109 | + @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class) | |
| 110 | + }) | |
| 111 | + public CommonResult<String> thirdLoginRedirect(@RequestParam("type") Integer type, | |
| 112 | + @RequestParam("redirectUri") String redirectUri) { | |
| 113 | + // 获得对应的 AuthRequest 实现 | |
| 114 | + AuthRequest authRequest = authRequestFactory.get(SysUserSocialTypeEnum.valueOfType(type).getSource()); | |
| 115 | + // 生成跳转地址 | |
| 116 | + String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); | |
| 117 | + authorizeUri = HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); | |
| 118 | + return CommonResult.success(authorizeUri); | |
| 119 | + } | |
| 120 | + | |
| 121 | + @PostMapping("/third-login") | |
| 122 | + @ApiOperation("三方登陆,使用 code 授权码") | |
| 123 | + @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | |
| 124 | + public CommonResult<SysAuthLoginRespVO> thirdLogin(@RequestBody @Valid SysAuthThirdLoginReqVO reqVO) { | |
| 125 | + String token = authService.thirdLogin(reqVO, getClientIP(), getUserAgent()); | |
| 126 | + return null; | |
| 127 | + } | |
| 128 | + | |
| 129 | + @RequestMapping("/{type}/callback") | |
| 130 | + public AuthResponse login(@PathVariable String type, AuthCallback callback) { | |
| 131 | + AuthRequest authRequest = authRequestFactory.get(type); | |
| 132 | + AuthResponse<AuthUser> response = authRequest.login(callback); | |
| 133 | + log.info("【response】= {}", JSONUtil.toJsonStr(response)); | |
| 134 | + return response; | |
| 135 | + } | |
| 136 | + | |
| 156 | 137 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/vo/auth/SysAuthThirdLoginReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | |
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 5 | +import io.swagger.annotations.ApiModel; | |
| 6 | +import io.swagger.annotations.ApiModelProperty; | |
| 7 | +import lombok.AllArgsConstructor; | |
| 8 | +import lombok.Builder; | |
| 9 | +import lombok.Data; | |
| 10 | +import lombok.NoArgsConstructor; | |
| 11 | +import org.hibernate.validator.constraints.Length; | |
| 12 | + | |
| 13 | +import javax.validation.constraints.NotEmpty; | |
| 14 | +import javax.validation.constraints.NotNull; | |
| 15 | +import javax.validation.constraints.Pattern; | |
| 16 | + | |
| 17 | +@ApiModel("三方登陆 Request VO,使用 code 授权码") | |
| 18 | +@Data | |
| 19 | +@NoArgsConstructor | |
| 20 | +@AllArgsConstructor | |
| 21 | +@Builder | |
| 22 | +public class SysAuthThirdLoginReqVO { | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "三方平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") | |
| 25 | + @InEnum(SysUserSocialTypeEnum.class) | |
| 26 | + @NotNull(message = "三方平台的类型不能为空") | |
| 27 | + private Integer type; | |
| 28 | + | |
| 29 | + @ApiModelProperty(value = "授权码", required = true, example = "1024") | |
| 30 | + @NotEmpty(message = "授权码不能为空") | |
| 31 | + private String code; | |
| 32 | + | |
| 33 | + @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") | |
| 34 | + @NotEmpty(message = "state 不能为空") | |
| 35 | + private String state; | |
| 36 | + | |
| 37 | +} | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/auth/SysAuthConvert.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.system.convert.auth; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO; |
| 4 | 4 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO; |
| 5 | +import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthThirdLoginReqVO; | |
| 5 | 6 | import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO; |
| 6 | 7 | import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO; |
| 7 | 8 | import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserCreateReqVO; |
| ... | ... | @@ -11,6 +12,7 @@ import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO |
| 11 | 12 | import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuIdEnum; |
| 12 | 13 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 13 | 14 | import cn.iocoder.yudao.framework.security.core.LoginUser; |
| 15 | +import me.zhyd.oauth.model.AuthCallback; | |
| 14 | 16 | import me.zhyd.oauth.model.AuthUser; |
| 15 | 17 | import org.mapstruct.Mapper; |
| 16 | 18 | import org.mapstruct.Mapping; |
| ... | ... | @@ -43,6 +45,8 @@ public interface SysAuthConvert { |
| 43 | 45 | |
| 44 | 46 | LoginUser convert(SysUserProfileUpdatePasswordReqVO reqVO); |
| 45 | 47 | |
| 48 | + AuthCallback convert(SysAuthThirdLoginReqVO bean); | |
| 49 | + | |
| 46 | 50 | /** |
| 47 | 51 | * 将菜单列表,构建成菜单树 |
| 48 | 52 | * | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/user/SysUserSocialDO.java
| ... | ... | @@ -41,6 +41,7 @@ public class SysUserSocialDO extends BaseDO { |
| 41 | 41 | * 三方平台的类型 |
| 42 | 42 | */ |
| 43 | 43 | private SysUserSocialTypeEnum type; |
| 44 | + | |
| 44 | 45 | /** |
| 45 | 46 | * 三方 openid |
| 46 | 47 | */ |
| ... | ... | @@ -56,6 +57,10 @@ public class SysUserSocialDO extends BaseDO { |
| 56 | 57 | * 如果没有 unionId 的平台,直接使用 openid 作为该字段的值 |
| 57 | 58 | */ |
| 58 | 59 | private String unionId; |
| 60 | + /** | |
| 61 | + * 原始 Token 数据,一般是 JSON 格式 | |
| 62 | + */ | |
| 63 | + private String rawTokenInfo; | |
| 59 | 64 | |
| 60 | 65 | /** |
| 61 | 66 | * 用户昵称 |
| ... | ... | @@ -66,9 +71,9 @@ public class SysUserSocialDO extends BaseDO { |
| 66 | 71 | */ |
| 67 | 72 | private String avatar; |
| 68 | 73 | /** |
| 69 | - * 原始数据,一般是 JSON 格式 | |
| 74 | + * 原始用户数据,一般是 JSON 格式 | |
| 70 | 75 | */ |
| 71 | - private String info; | |
| 76 | + private String rawUserInfo; | |
| 72 | 77 | |
| 73 | 78 | } |
| 74 | 79 | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/user/SysUserSocialTypeEnum.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.system.enums.user; |
| 3 | 3 | import cn.hutool.core.util.ArrayUtil; |
| 4 | 4 | import cn.iocoder.yudao.adminserver.modules.system.enums.errorcode.SysErrorCodeTypeEnum; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; |
| 6 | +import com.fasterxml.jackson.annotation.JsonCreator; | |
| 6 | 7 | import jodd.util.ArraysUtil; |
| 7 | 8 | import lombok.AllArgsConstructor; |
| 8 | 9 | import lombok.Getter; |
| ... | ... | @@ -19,6 +20,7 @@ import java.util.Arrays; |
| 19 | 20 | public enum SysUserSocialTypeEnum implements IntArrayValuable { |
| 20 | 21 | |
| 21 | 22 | GITEE(10, "GITEE"), // https://gitee.com/api/v5/oauth_doc#/ |
| 23 | + DINGTALK(20, "DINGTALK"), // https://developers.dingtalk.com/document/app/obtain-identity-credentials | |
| 22 | 24 | ; |
| 23 | 25 | |
| 24 | 26 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysUserSocialTypeEnum::getType).toArray(); | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthService.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.system.service.auth; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthThirdLoginReqVO; | |
| 3 | 4 | import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; |
| 4 | 5 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; |
| 5 | 6 | |
| ... | ... | @@ -22,4 +23,14 @@ public interface SysAuthService extends SecurityAuthFrameworkService { |
| 22 | 23 | */ |
| 23 | 24 | String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent); |
| 24 | 25 | |
| 26 | + /** | |
| 27 | + * 三方登陆用户,使用 code 授权码 | |
| 28 | + * | |
| 29 | + * @param reqVO 登陆信息 | |
| 30 | + * @param userIp 用户 IP | |
| 31 | + * @param userAgent 用户 UA | |
| 32 | + * @return 身份令牌,使用 JWT 方式 | |
| 33 | + */ | |
| 34 | + String thirdLogin(SysAuthThirdLoginReqVO reqVO, String userIp, String userAgent); | |
| 35 | + | |
| 25 | 36 | } | ... | ... |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.adminserver.modules.system.service.auth.impl; |
| 2 | 2 | |
| 3 | +import cn.hutool.json.JSONUtil; | |
| 4 | +import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthThirdLoginReqVO; | |
| 5 | +import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | |
| 3 | 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | 7 | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; |
| 8 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 5 | 9 | import cn.iocoder.yudao.framework.security.core.LoginUser; |
| 6 | 10 | import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; |
| 7 | 11 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; |
| ... | ... | @@ -17,7 +21,12 @@ import cn.iocoder.yudao.adminserver.modules.system.service.logger.SysLoginLogSer |
| 17 | 21 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; |
| 18 | 22 | import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; |
| 19 | 23 | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; |
| 24 | +import com.xkcoding.justauth.AuthRequestFactory; | |
| 20 | 25 | import lombok.extern.slf4j.Slf4j; |
| 26 | +import me.zhyd.oauth.model.AuthCallback; | |
| 27 | +import me.zhyd.oauth.model.AuthResponse; | |
| 28 | +import me.zhyd.oauth.model.AuthUser; | |
| 29 | +import me.zhyd.oauth.request.AuthRequest; | |
| 21 | 30 | import org.springframework.context.annotation.Lazy; |
| 22 | 31 | import org.springframework.security.authentication.AuthenticationManager; |
| 23 | 32 | import org.springframework.security.authentication.BadCredentialsException; |
| ... | ... | @@ -60,6 +69,9 @@ public class SysAuthServiceImpl implements SysAuthService { |
| 60 | 69 | @Resource |
| 61 | 70 | private SysUserSessionService userSessionService; |
| 62 | 71 | |
| 72 | + @Resource | |
| 73 | + private AuthRequestFactory authRequestFactory; | |
| 74 | + | |
| 63 | 75 | @Override |
| 64 | 76 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |
| 65 | 77 | // 获取 username 对应的 SysUserDO |
| ... | ... | @@ -97,6 +109,24 @@ public class SysAuthServiceImpl implements SysAuthService { |
| 97 | 109 | return userSessionService.createUserSession(loginUser, userIp, userAgent); |
| 98 | 110 | } |
| 99 | 111 | |
| 112 | + @Override | |
| 113 | + public String thirdLogin(SysAuthThirdLoginReqVO reqVO, String userIp, String userAgent) { | |
| 114 | + // 使用 code 授权码,进行登陆 | |
| 115 | + AuthRequest authRequest = authRequestFactory.get(SysUserSocialTypeEnum.valueOfType(reqVO.getType()).getSource()); | |
| 116 | + AuthCallback authCallback = SysAuthConvert.INSTANCE.convert(reqVO); | |
| 117 | + AuthResponse<?> authResponse = authRequest.login(authCallback); | |
| 118 | + log.info("[thirdLogin][请求三方平台 type({}) request({}) response({})]", reqVO.getType(), JsonUtils.toJsonString(authCallback), | |
| 119 | + JsonUtils.toJsonString(authResponse)); | |
| 120 | + if (!authResponse.ok()) { | |
| 121 | + throw new RuntimeException(""); // TODO 芋艿:补全 | |
| 122 | + } | |
| 123 | + AuthUser authUser = (AuthUser) authResponse.getData(); | |
| 124 | + | |
| 125 | + // 查找到对应的 | |
| 126 | + | |
| 127 | + return null; | |
| 128 | + } | |
| 129 | + | |
| 100 | 130 | private void verifyCaptcha(String username, String captchaUUID, String captchaCode) { |
| 101 | 131 | String code = captchaService.getCaptchaCode(captchaUUID); |
| 102 | 132 | // 验证码不存在 | ... | ... |
yudao-admin-server/src/main/resources/application-local.yaml
| ... | ... | @@ -173,8 +173,12 @@ justauth: |
| 173 | 173 | type: |
| 174 | 174 | GITEE: |
| 175 | 175 | client-id: 6bb0b37a8a017e5e2dc4c34ca4756dcf80e8e392585e7035d3ede7a6db50426e |
| 176 | - client-secret: f117b9de5e9267bcd48db83d4cb078ea8cf9a5d17cda83481e3d9090df3fa01d | |
| 176 | + client-secret: ba9f1f42e77be71f461b54da83b6f4b45a052dd7f93418f00f91f4e6934dfd1f | |
| 177 | 177 | ignore-check-redirect-uri: true |
| 178 | 178 | # redirect-uri: http://127.0.0.1:48080/api/gitee/callback |
| 179 | + DINGTALK: | |
| 180 | + client-id: dingvrnreaje3yqvzhxg | |
| 181 | + client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI | |
| 182 | + ignore-check-redirect-uri: true | |
| 179 | 183 | cache: |
| 180 | 184 | type: default | ... | ... |
yudao-admin-ui/src/api/login.js
| ... | ... | @@ -39,18 +39,23 @@ export function getCodeImg() { |
| 39 | 39 | }) |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | -// 接入第三方登录 | |
| 43 | -export function oAuthLogin(type, redirectUri) { | |
| 42 | +// 三方登陆的跳转 | |
| 43 | +export function thirdLoginRedirect(type, redirectUri) { | |
| 44 | 44 | return request({ |
| 45 | 45 | url: '/third-login-redirect?type=' + type + '&redirectUri=' + redirectUri, |
| 46 | 46 | method: 'get' |
| 47 | 47 | }) |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | -export function getToken(path) { | |
| 51 | - console.log({path}); | |
| 50 | +// 三方登陆,使用 code 授权码 | |
| 51 | +export function thirdLogin(type, code, state) { | |
| 52 | 52 | return request({ |
| 53 | - url: '/auth2/login/github' + path, | |
| 54 | - method: 'get' | |
| 53 | + url: '/third-login', | |
| 54 | + method: 'post', | |
| 55 | + data: { | |
| 56 | + type, | |
| 57 | + code, | |
| 58 | + state | |
| 59 | + } | |
| 55 | 60 | }) |
| 56 | 61 | } | ... | ... |
yudao-admin-ui/src/permission.js
| ... | ... | @@ -7,7 +7,7 @@ import { getToken } from '@/utils/auth' |
| 7 | 7 | |
| 8 | 8 | NProgress.configure({ showSpinner: false }) |
| 9 | 9 | |
| 10 | -const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/oauthLogin/gitee'] | |
| 10 | +const whiteList = ['/login', '/third-login', '/auth-redirect', '/bind', '/register', '/oauthLogin/gitee'] | |
| 11 | 11 | |
| 12 | 12 | router.beforeEach((to, from, next) => { |
| 13 | 13 | NProgress.start() | ... | ... |
yudao-admin-ui/src/router/index.js
| ... | ... | @@ -44,8 +44,8 @@ export const constantRoutes = [ |
| 44 | 44 | hidden: true |
| 45 | 45 | }, |
| 46 | 46 | { |
| 47 | - path: '/oauthLogin/gitee', | |
| 48 | - component: (resolve) => require(['@/views/oauthLogin'], resolve), | |
| 47 | + path: '/third-login', | |
| 48 | + component: (resolve) => require(['@/views/thirdLogin'], resolve), | |
| 49 | 49 | hidden: true |
| 50 | 50 | }, |
| 51 | 51 | { | ... | ... |
yudao-admin-ui/src/utils/constants.js
yudao-admin-ui/src/views/login.vue
| ... | ... | @@ -45,7 +45,7 @@ |
| 45 | 45 | </template> |
| 46 | 46 | |
| 47 | 47 | <script> |
| 48 | -import { getCodeImg,oAuthLogin } from "@/api/login"; | |
| 48 | +import { getCodeImg,thirdLoginRedirect } from "@/api/login"; | |
| 49 | 49 | import Cookies from "js-cookie"; |
| 50 | 50 | import { encrypt, decrypt } from '@/utils/jsencrypt' |
| 51 | 51 | |
| ... | ... | @@ -54,7 +54,6 @@ export default { |
| 54 | 54 | data() { |
| 55 | 55 | return { |
| 56 | 56 | codeUrl: "", |
| 57 | - cookiePassword: "", | |
| 58 | 57 | loginForm: { |
| 59 | 58 | username: "admin", |
| 60 | 59 | password: "admin123", |
| ... | ... | @@ -68,13 +67,10 @@ export default { |
| 68 | 67 | source: "gitee", |
| 69 | 68 | type: 10 |
| 70 | 69 | }, { |
| 71 | - img: "https://cdn.jsdelivr.net/gh/justauth/justauth-oauth-logo@1.2/wechat.png", | |
| 72 | - title: "微信", | |
| 73 | - source: "weixin" | |
| 74 | - }, { | |
| 75 | - img: "https://cdn.jsdelivr.net/gh/justauth/justauth-oauth-logo@1.2/qq.png", | |
| 76 | - title: "QQ", | |
| 77 | - source: "qq" | |
| 70 | + img: "https://cdn.jsdelivr.net/gh/justauth/justauth-oauth-logo@1.2/dingtalk.png", | |
| 71 | + title: "钉钉", | |
| 72 | + source: "dingtalk", | |
| 73 | + type: 20 | |
| 78 | 74 | } |
| 79 | 75 | ], |
| 80 | 76 | loginRules: { |
| ... | ... | @@ -147,9 +143,11 @@ export default { |
| 147 | 143 | // 设置登陆中 |
| 148 | 144 | this.loading = true; |
| 149 | 145 | // 计算 redirectUri |
| 150 | - const redirectUri = location.origin + '/third-login'; | |
| 146 | + // const redirectUri = location.origin + '/third-login'; | |
| 147 | + // const redirectUri = 'http://127.0.0.1:48080/api/gitee/callback'; | |
| 148 | + const redirectUri = 'http://127.0.0.1:48080/api/dingtalk/callback'; | |
| 151 | 149 | // 进行跳转 |
| 152 | - oAuthLogin(provider.type, redirectUri).then((res) => { | |
| 150 | + thirdLoginRedirect(provider.type, redirectUri).then((res) => { | |
| 153 | 151 | // console.log(res.url); |
| 154 | 152 | window.location.href = res.data; |
| 155 | 153 | }); | ... | ... |
yudao-admin-ui/src/views/oauthLogin.vue deleted
| 1 | -<template> | |
| 2 | -</template> | |
| 3 | - | |
| 4 | -<script> | |
| 5 | -import { setToken } from '@/utils/auth' | |
| 6 | - | |
| 7 | -export default { | |
| 8 | - created() { | |
| 9 | - const {token} = this.$route.query; | |
| 10 | - setToken(token); | |
| 11 | - this.$router.push({ path: this.redirect || "/" }).catch(() => {}); | |
| 12 | - }, | |
| 13 | -} | |
| 14 | -</script> | |
| 15 | - | |
| 16 | -<style> | |
| 17 | - | |
| 18 | -</style> |
yudao-admin-ui/src/views/thirdLogin.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="login"> | |
| 3 | + <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> | |
| 4 | + <h3 class="title">绑定账号</h3> | |
| 5 | + <el-form-item prop="username"> | |
| 6 | + <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号"> | |
| 7 | + <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> | |
| 8 | + </el-input> | |
| 9 | + </el-form-item> | |
| 10 | + <el-form-item prop="password"> | |
| 11 | + <el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin"> | |
| 12 | + <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> | |
| 13 | + </el-input> | |
| 14 | + </el-form-item> | |
| 15 | + <el-form-item style="width:100%;"> | |
| 16 | + <el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin"> | |
| 17 | + <span v-if="!loading">提 交</span> | |
| 18 | + <span v-else>提 交 中...</span> | |
| 19 | + </el-button> | |
| 20 | + </el-form-item> | |
| 21 | + | |
| 22 | + </el-form> | |
| 23 | + <!-- 底部 --> | |
| 24 | + <div class="el-login-footer"> | |
| 25 | + <span>Copyright © 2020-2021 iocoder.cn All Rights Reserved.</span> | |
| 26 | + </div> | |
| 27 | + </div> | |
| 28 | +</template> | |
| 29 | + | |
| 30 | +<script> | |
| 31 | +import { thirdLogin } from "@/api/login"; | |
| 32 | +import Cookies from "js-cookie"; | |
| 33 | +import { encrypt, decrypt } from '@/utils/jsencrypt' | |
| 34 | + | |
| 35 | +export default { | |
| 36 | + name: "ThirdLogin", | |
| 37 | + data() { | |
| 38 | + return { | |
| 39 | + loginForm: { | |
| 40 | + username: "admin", | |
| 41 | + password: "admin123", | |
| 42 | + rememberMe: false, | |
| 43 | + }, | |
| 44 | + loginRules: { | |
| 45 | + username: [ | |
| 46 | + { required: true, trigger: "blur", message: "用户名不能为空" } | |
| 47 | + ], | |
| 48 | + password: [ | |
| 49 | + { required: true, trigger: "blur", message: "密码不能为空" } | |
| 50 | + ], | |
| 51 | + }, | |
| 52 | + loading: false, | |
| 53 | + redirect: undefined, | |
| 54 | + // 三方登陆相关 | |
| 55 | + type: undefined, | |
| 56 | + code: undefined, | |
| 57 | + state: undefined, | |
| 58 | + }; | |
| 59 | + }, | |
| 60 | + watch: { | |
| 61 | + $route: { | |
| 62 | + handler: function(route) { | |
| 63 | + this.redirect = route.query && route.query.redirect; | |
| 64 | + }, | |
| 65 | + immediate: true | |
| 66 | + } | |
| 67 | + }, | |
| 68 | + created() { | |
| 69 | + this.getCookie(); | |
| 70 | + // 三方登陆相关 | |
| 71 | + this.type = 10; | |
| 72 | + this.code = this.$route.query.code; | |
| 73 | + this.state = this.$route.query.state; | |
| 74 | + thirdLogin(this.type, this.code, this.state).then(res => { | |
| 75 | + debugger | |
| 76 | + }); | |
| 77 | + }, | |
| 78 | + methods: { | |
| 79 | + getCookie() { | |
| 80 | + const username = Cookies.get("username"); | |
| 81 | + const password = Cookies.get("password"); | |
| 82 | + const rememberMe = Cookies.get('rememberMe') | |
| 83 | + this.loginForm = { | |
| 84 | + username: username === undefined ? this.loginForm.username : username, | |
| 85 | + password: password === undefined ? this.loginForm.password : decrypt(password), | |
| 86 | + rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) | |
| 87 | + }; | |
| 88 | + }, | |
| 89 | + handleLogin() { | |
| 90 | + this.$refs.loginForm.validate(valid => { | |
| 91 | + if (valid) { | |
| 92 | + this.loading = true; | |
| 93 | + if (this.loginForm.rememberMe) { | |
| 94 | + Cookies.set("username", this.loginForm.username, { expires: 30 }); | |
| 95 | + Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); | |
| 96 | + } else { | |
| 97 | + Cookies.remove("username"); | |
| 98 | + Cookies.remove("password"); | |
| 99 | + } | |
| 100 | + this.$store.dispatch("Login", this.loginForm).then(() => { | |
| 101 | + this.$router.push({ path: this.redirect || "/" }).catch(()=>{}); | |
| 102 | + }).catch(() => { | |
| 103 | + this.loading = false; | |
| 104 | + }); | |
| 105 | + } | |
| 106 | + }); | |
| 107 | + } | |
| 108 | + } | |
| 109 | +}; | |
| 110 | +</script> | |
| 111 | + | |
| 112 | +<style rel="stylesheet/scss" lang="scss"> | |
| 113 | +.login { | |
| 114 | + display: flex; | |
| 115 | + justify-content: center; | |
| 116 | + align-items: center; | |
| 117 | + height: 100%; | |
| 118 | + background-image: url("http://static.yudao.iocoder.cn/login-background.jpg"); | |
| 119 | + background-size: cover; | |
| 120 | +} | |
| 121 | +.title { | |
| 122 | + margin: 0px auto 30px auto; | |
| 123 | + text-align: center; | |
| 124 | + color: #707070; | |
| 125 | +} | |
| 126 | + | |
| 127 | +.login-form { | |
| 128 | + border-radius: 6px; | |
| 129 | + background: #ffffff; | |
| 130 | + width: 400px; | |
| 131 | + padding: 25px 25px 5px 25px; | |
| 132 | + .el-input { | |
| 133 | + height: 38px; | |
| 134 | + input { | |
| 135 | + height: 38px; | |
| 136 | + } | |
| 137 | + } | |
| 138 | + .input-icon { | |
| 139 | + height: 39px; | |
| 140 | + width: 14px; | |
| 141 | + margin-left: 2px; | |
| 142 | + } | |
| 143 | +} | |
| 144 | +.login-tip { | |
| 145 | + font-size: 13px; | |
| 146 | + text-align: center; | |
| 147 | + color: #bfbfbf; | |
| 148 | +} | |
| 149 | +.login-code { | |
| 150 | + width: 33%; | |
| 151 | + height: 38px; | |
| 152 | + float: right; | |
| 153 | + img { | |
| 154 | + cursor: pointer; | |
| 155 | + vertical-align: middle; | |
| 156 | + } | |
| 157 | +} | |
| 158 | +.el-login-footer { | |
| 159 | + height: 40px; | |
| 160 | + line-height: 40px; | |
| 161 | + position: fixed; | |
| 162 | + bottom: 0; | |
| 163 | + width: 100%; | |
| 164 | + text-align: center; | |
| 165 | + color: #fff; | |
| 166 | + font-family: Arial; | |
| 167 | + font-size: 12px; | |
| 168 | + letter-spacing: 1px; | |
| 169 | +} | |
| 170 | +.login-code-img { | |
| 171 | + height: 38px; | |
| 172 | +} | |
| 173 | +</style> | ... | ... |