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 | package cn.iocoder.yudao.adminserver.modules.system.controller.auth; | 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 | import cn.hutool.json.JSONUtil; | 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 | import cn.iocoder.yudao.adminserver.modules.system.convert.auth.SysAuthConvert; | 5 | import cn.iocoder.yudao.adminserver.modules.system.convert.auth.SysAuthConvert; |
| 17 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysMenuDO; | 6 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysMenuDO; |
| 18 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysRoleDO; | 7 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.permission.SysRoleDO; |
| 19 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; | 8 | import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; |
| 20 | import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuTypeEnum; | 9 | import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuTypeEnum; |
| 10 | +import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysUserSocialTypeEnum; | ||
| 21 | import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysAuthService; | 11 | import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysAuthService; |
| 22 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; | 12 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; |
| 23 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService; | 13 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService; |
| 24 | import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | 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 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | 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 | import com.xkcoding.justauth.AuthRequestFactory; | 20 | import com.xkcoding.justauth.AuthRequestFactory; |
| 28 | import io.swagger.annotations.Api; | 21 | import io.swagger.annotations.Api; |
| 29 | import io.swagger.annotations.ApiImplicitParam; | 22 | import io.swagger.annotations.ApiImplicitParam; |
| @@ -35,26 +28,18 @@ import me.zhyd.oauth.model.AuthResponse; | @@ -35,26 +28,18 @@ import me.zhyd.oauth.model.AuthResponse; | ||
| 35 | import me.zhyd.oauth.model.AuthUser; | 28 | import me.zhyd.oauth.model.AuthUser; |
| 36 | import me.zhyd.oauth.request.AuthRequest; | 29 | import me.zhyd.oauth.request.AuthRequest; |
| 37 | import me.zhyd.oauth.utils.AuthStateUtils; | 30 | import me.zhyd.oauth.utils.AuthStateUtils; |
| 38 | -import org.apache.commons.lang.StringUtils; | ||
| 39 | -import org.quartz.SimpleTrigger; | ||
| 40 | import org.springframework.validation.annotation.Validated; | 31 | import org.springframework.validation.annotation.Validated; |
| 41 | import org.springframework.web.bind.annotation.*; | 32 | import org.springframework.web.bind.annotation.*; |
| 42 | -import org.springframework.web.multipart.MultipartFile; | ||
| 43 | -import org.springframework.web.util.UriBuilder; | ||
| 44 | 33 | ||
| 45 | import javax.annotation.Resource; | 34 | import javax.annotation.Resource; |
| 46 | -import javax.servlet.http.HttpServletResponse; | ||
| 47 | import javax.validation.Valid; | 35 | import javax.validation.Valid; |
| 48 | -import java.io.IOException; | ||
| 49 | -import java.net.URL; | ||
| 50 | -import java.nio.charset.Charset; | ||
| 51 | import java.util.List; | 36 | import java.util.List; |
| 52 | 37 | ||
| 53 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 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 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | 39 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |
| 57 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent; | 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 | @Api(tags = "认证") | 44 | @Api(tags = "认证") |
| 60 | @RestController | 45 | @RestController |
| @@ -71,8 +56,6 @@ public class SysAuthController { | @@ -71,8 +56,6 @@ public class SysAuthController { | ||
| 71 | private SysRoleService roleService; | 56 | private SysRoleService roleService; |
| 72 | @Resource | 57 | @Resource |
| 73 | private SysPermissionService permissionService; | 58 | private SysPermissionService permissionService; |
| 74 | - @Resource | ||
| 75 | - private SysUserSessionService sysUserSessionService; | ||
| 76 | 59 | ||
| 77 | @Resource | 60 | @Resource |
| 78 | private AuthRequestFactory authRequestFactory; | 61 | private AuthRequestFactory authRequestFactory; |
| @@ -86,42 +69,6 @@ public class SysAuthController { | @@ -86,42 +69,6 @@ public class SysAuthController { | ||
| 86 | return success(SysAuthLoginRespVO.builder().token(token).build()); | 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 | @GetMapping("/get-permission-info") | 72 | @GetMapping("/get-permission-info") |
| 126 | @ApiOperation("获取登陆用户的权限信息") | 73 | @ApiOperation("获取登陆用户的权限信息") |
| 127 | public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() { | 74 | public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() { |
| @@ -153,4 +100,38 @@ public class SysAuthController { | @@ -153,4 +100,38 @@ public class SysAuthController { | ||
| 153 | return success(SysAuthConvert.INSTANCE.buildMenuTree(menuList)); | 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,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.system.convert.auth; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO; | 3 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO; |
| 4 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO; | 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 | import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO; | 6 | import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO; |
| 6 | import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO; | 7 | import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO; |
| 7 | import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserCreateReqVO; | 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,6 +12,7 @@ import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO | ||
| 11 | import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuIdEnum; | 12 | import cn.iocoder.yudao.adminserver.modules.system.enums.permission.MenuIdEnum; |
| 12 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 13 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 13 | import cn.iocoder.yudao.framework.security.core.LoginUser; | 14 | import cn.iocoder.yudao.framework.security.core.LoginUser; |
| 15 | +import me.zhyd.oauth.model.AuthCallback; | ||
| 14 | import me.zhyd.oauth.model.AuthUser; | 16 | import me.zhyd.oauth.model.AuthUser; |
| 15 | import org.mapstruct.Mapper; | 17 | import org.mapstruct.Mapper; |
| 16 | import org.mapstruct.Mapping; | 18 | import org.mapstruct.Mapping; |
| @@ -43,6 +45,8 @@ public interface SysAuthConvert { | @@ -43,6 +45,8 @@ public interface SysAuthConvert { | ||
| 43 | 45 | ||
| 44 | LoginUser convert(SysUserProfileUpdatePasswordReqVO reqVO); | 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,6 +41,7 @@ public class SysUserSocialDO extends BaseDO { | ||
| 41 | * 三方平台的类型 | 41 | * 三方平台的类型 |
| 42 | */ | 42 | */ |
| 43 | private SysUserSocialTypeEnum type; | 43 | private SysUserSocialTypeEnum type; |
| 44 | + | ||
| 44 | /** | 45 | /** |
| 45 | * 三方 openid | 46 | * 三方 openid |
| 46 | */ | 47 | */ |
| @@ -56,6 +57,10 @@ public class SysUserSocialDO extends BaseDO { | @@ -56,6 +57,10 @@ public class SysUserSocialDO extends BaseDO { | ||
| 56 | * 如果没有 unionId 的平台,直接使用 openid 作为该字段的值 | 57 | * 如果没有 unionId 的平台,直接使用 openid 作为该字段的值 |
| 57 | */ | 58 | */ |
| 58 | private String unionId; | 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,9 +71,9 @@ public class SysUserSocialDO extends BaseDO { | ||
| 66 | */ | 71 | */ |
| 67 | private String avatar; | 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,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.system.enums.user; | ||
| 3 | import cn.hutool.core.util.ArrayUtil; | 3 | import cn.hutool.core.util.ArrayUtil; |
| 4 | import cn.iocoder.yudao.adminserver.modules.system.enums.errorcode.SysErrorCodeTypeEnum; | 4 | import cn.iocoder.yudao.adminserver.modules.system.enums.errorcode.SysErrorCodeTypeEnum; |
| 5 | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | 5 | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; |
| 6 | +import com.fasterxml.jackson.annotation.JsonCreator; | ||
| 6 | import jodd.util.ArraysUtil; | 7 | import jodd.util.ArraysUtil; |
| 7 | import lombok.AllArgsConstructor; | 8 | import lombok.AllArgsConstructor; |
| 8 | import lombok.Getter; | 9 | import lombok.Getter; |
| @@ -19,6 +20,7 @@ import java.util.Arrays; | @@ -19,6 +20,7 @@ import java.util.Arrays; | ||
| 19 | public enum SysUserSocialTypeEnum implements IntArrayValuable { | 20 | public enum SysUserSocialTypeEnum implements IntArrayValuable { |
| 20 | 21 | ||
| 21 | GITEE(10, "GITEE"), // https://gitee.com/api/v5/oauth_doc#/ | 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 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysUserSocialTypeEnum::getType).toArray(); | 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 | package cn.iocoder.yudao.adminserver.modules.system.service.auth; | 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 | import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; | 4 | import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; |
| 4 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; | 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,4 +23,14 @@ public interface SysAuthService extends SecurityAuthFrameworkService { | ||
| 22 | */ | 23 | */ |
| 23 | String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent); | 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 | package cn.iocoder.yudao.adminserver.modules.system.service.auth.impl; | 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 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | 7 | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; |
| 8 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||
| 5 | import cn.iocoder.yudao.framework.security.core.LoginUser; | 9 | import cn.iocoder.yudao.framework.security.core.LoginUser; |
| 6 | import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; | 10 | import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; |
| 7 | import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; | 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,7 +21,12 @@ import cn.iocoder.yudao.adminserver.modules.system.service.logger.SysLoginLogSer | ||
| 17 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; | 21 | import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; |
| 18 | import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | 22 | import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; |
| 19 | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | 23 | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; |
| 24 | +import com.xkcoding.justauth.AuthRequestFactory; | ||
| 20 | import lombok.extern.slf4j.Slf4j; | 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 | import org.springframework.context.annotation.Lazy; | 30 | import org.springframework.context.annotation.Lazy; |
| 22 | import org.springframework.security.authentication.AuthenticationManager; | 31 | import org.springframework.security.authentication.AuthenticationManager; |
| 23 | import org.springframework.security.authentication.BadCredentialsException; | 32 | import org.springframework.security.authentication.BadCredentialsException; |
| @@ -60,6 +69,9 @@ public class SysAuthServiceImpl implements SysAuthService { | @@ -60,6 +69,9 @@ public class SysAuthServiceImpl implements SysAuthService { | ||
| 60 | @Resource | 69 | @Resource |
| 61 | private SysUserSessionService userSessionService; | 70 | private SysUserSessionService userSessionService; |
| 62 | 71 | ||
| 72 | + @Resource | ||
| 73 | + private AuthRequestFactory authRequestFactory; | ||
| 74 | + | ||
| 63 | @Override | 75 | @Override |
| 64 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | 76 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |
| 65 | // 获取 username 对应的 SysUserDO | 77 | // 获取 username 对应的 SysUserDO |
| @@ -97,6 +109,24 @@ public class SysAuthServiceImpl implements SysAuthService { | @@ -97,6 +109,24 @@ public class SysAuthServiceImpl implements SysAuthService { | ||
| 97 | return userSessionService.createUserSession(loginUser, userIp, userAgent); | 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 | private void verifyCaptcha(String username, String captchaUUID, String captchaCode) { | 130 | private void verifyCaptcha(String username, String captchaUUID, String captchaCode) { |
| 101 | String code = captchaService.getCaptchaCode(captchaUUID); | 131 | String code = captchaService.getCaptchaCode(captchaUUID); |
| 102 | // 验证码不存在 | 132 | // 验证码不存在 |
yudao-admin-server/src/main/resources/application-local.yaml
| @@ -173,8 +173,12 @@ justauth: | @@ -173,8 +173,12 @@ justauth: | ||
| 173 | type: | 173 | type: |
| 174 | GITEE: | 174 | GITEE: |
| 175 | client-id: 6bb0b37a8a017e5e2dc4c34ca4756dcf80e8e392585e7035d3ede7a6db50426e | 175 | client-id: 6bb0b37a8a017e5e2dc4c34ca4756dcf80e8e392585e7035d3ede7a6db50426e |
| 176 | - client-secret: f117b9de5e9267bcd48db83d4cb078ea8cf9a5d17cda83481e3d9090df3fa01d | 176 | + client-secret: ba9f1f42e77be71f461b54da83b6f4b45a052dd7f93418f00f91f4e6934dfd1f |
| 177 | ignore-check-redirect-uri: true | 177 | ignore-check-redirect-uri: true |
| 178 | # redirect-uri: http://127.0.0.1:48080/api/gitee/callback | 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 | cache: | 183 | cache: |
| 180 | type: default | 184 | type: default |
yudao-admin-ui/src/api/login.js
| @@ -39,18 +39,23 @@ export function getCodeImg() { | @@ -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 | return request({ | 44 | return request({ |
| 45 | url: '/third-login-redirect?type=' + type + '&redirectUri=' + redirectUri, | 45 | url: '/third-login-redirect?type=' + type + '&redirectUri=' + redirectUri, |
| 46 | method: 'get' | 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 | return request({ | 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 +7,7 @@ import { getToken } from '@/utils/auth' | ||
| 7 | 7 | ||
| 8 | NProgress.configure({ showSpinner: false }) | 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 | router.beforeEach((to, from, next) => { | 12 | router.beforeEach((to, from, next) => { |
| 13 | NProgress.start() | 13 | NProgress.start() |
yudao-admin-ui/src/router/index.js
| @@ -44,8 +44,8 @@ export const constantRoutes = [ | @@ -44,8 +44,8 @@ export const constantRoutes = [ | ||
| 44 | hidden: true | 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 | hidden: true | 49 | hidden: true |
| 50 | }, | 50 | }, |
| 51 | { | 51 | { |
yudao-admin-ui/src/utils/constants.js
| @@ -66,3 +66,11 @@ export const InfApiErrorLogProcessStatusEnum = { | @@ -66,3 +66,11 @@ export const InfApiErrorLogProcessStatusEnum = { | ||
| 66 | DONE: 1, // 已处理 | 66 | DONE: 1, // 已处理 |
| 67 | IGNORE: 2, // 已忽略 | 67 | IGNORE: 2, // 已忽略 |
| 68 | } | 68 | } |
| 69 | + | ||
| 70 | +/** | ||
| 71 | + * 用户的三方平台的类型枚举 | ||
| 72 | + */ | ||
| 73 | +export const SysUserSocialTypeEnum = { | ||
| 74 | + GITEE: 10, | ||
| 75 | + DINGTALK: 20, | ||
| 76 | +} |
yudao-admin-ui/src/views/login.vue
| @@ -45,7 +45,7 @@ | @@ -45,7 +45,7 @@ | ||
| 45 | </template> | 45 | </template> |
| 46 | 46 | ||
| 47 | <script> | 47 | <script> |
| 48 | -import { getCodeImg,oAuthLogin } from "@/api/login"; | 48 | +import { getCodeImg,thirdLoginRedirect } from "@/api/login"; |
| 49 | import Cookies from "js-cookie"; | 49 | import Cookies from "js-cookie"; |
| 50 | import { encrypt, decrypt } from '@/utils/jsencrypt' | 50 | import { encrypt, decrypt } from '@/utils/jsencrypt' |
| 51 | 51 | ||
| @@ -54,7 +54,6 @@ export default { | @@ -54,7 +54,6 @@ export default { | ||
| 54 | data() { | 54 | data() { |
| 55 | return { | 55 | return { |
| 56 | codeUrl: "", | 56 | codeUrl: "", |
| 57 | - cookiePassword: "", | ||
| 58 | loginForm: { | 57 | loginForm: { |
| 59 | username: "admin", | 58 | username: "admin", |
| 60 | password: "admin123", | 59 | password: "admin123", |
| @@ -68,13 +67,10 @@ export default { | @@ -68,13 +67,10 @@ export default { | ||
| 68 | source: "gitee", | 67 | source: "gitee", |
| 69 | type: 10 | 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 | loginRules: { | 76 | loginRules: { |
| @@ -147,9 +143,11 @@ export default { | @@ -147,9 +143,11 @@ export default { | ||
| 147 | // 设置登陆中 | 143 | // 设置登陆中 |
| 148 | this.loading = true; | 144 | this.loading = true; |
| 149 | // 计算 redirectUri | 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 | // console.log(res.url); | 151 | // console.log(res.url); |
| 154 | window.location.href = res.data; | 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> |