@@ -18,7 +18,6 @@ target/ | |||
*.iws | |||
*.iml | |||
*.ipr | |||
### NetBeans ### | |||
/nbproject/private/ | |||
/nbbuild/ | |||
@@ -31,3 +30,10 @@ build/ | |||
### VS Code ### | |||
.vscode/ | |||
/.idea | |||
/.vscode | |||
/.svn | |||
tuoheng-ui | |||
target/ | |||
HELP.md |
@@ -10,5 +10,15 @@ public class ThirdConstant { | |||
public static final String OAUTH_URL = "xxxxx.xxxx"; | |||
public static String GZJJ_USERNAME = "gzjj"; | |||
public static String GZJJ_PASSWORD = "gzjj@2023"; | |||
public static String HLCG_USERNAME = "hlcgadmin"; | |||
public static String HLCG_PASSWORD = "thjs2023"; | |||
public static String TUOHENG_AIRPORT_ADMIN = "tuoheng-airport-admin"; | |||
public static String TUOHENG_TELECOMUMALE_ADMIN = "tuoheng-telecomumale-admin"; | |||
} |
@@ -21,7 +21,6 @@ import javax.servlet.http.HttpServletResponse; | |||
@RestController | |||
@RequestMapping("/third") | |||
@Slf4j | |||
@CrossOrigin(origins = "https://airport.t-aaron.com") | |||
public class ThirdController { | |||
@Autowired | |||
@@ -32,9 +31,16 @@ public class ThirdController { | |||
return thirdService.authorize(clientId); | |||
} | |||
@CrossOrigin(origins = "https://airport.t-aaron.com") | |||
@GetMapping(value = "/redirect") | |||
public void redirect(HttpServletRequest req, HttpServletResponse resp) throws Exception { | |||
public void airportRedirect(HttpServletRequest req, HttpServletResponse resp) throws Exception { | |||
log.info("访问airport"); | |||
resp.sendRedirect("https://airport.t-aaron.com/transfer"); | |||
} | |||
@CrossOrigin(origins = "https://telecomumale.t-aaron.com") | |||
@GetMapping(value = "/telecomumaleRedirect") | |||
public void redirect(HttpServletRequest req, HttpServletResponse resp) throws Exception { | |||
resp.sendRedirect("https://telecomumale.t-aaron.com/transfer"); | |||
} | |||
} |
@@ -7,6 +7,7 @@ import com.tuoheng.exception.DiyException; | |||
import com.tuoheng.mapper.RegisteredClientMapper; | |||
import com.tuoheng.model.dto.ClientRoleDto; | |||
import com.tuoheng.model.po.RegisteredClientPo; | |||
import com.tuoheng.model.po.UserPo; | |||
import com.tuoheng.model.result.ProfileResult; | |||
import com.tuoheng.model.result.TokenResult; | |||
import com.tuoheng.service.ThirdService; | |||
@@ -44,10 +45,6 @@ public class ThirdServiceImpl implements ThirdService { | |||
@Autowired | |||
private RegisteredClientMapper registeredClientMapper; | |||
private static String username = "gzjj"; | |||
private static String password = "gzjj@2023"; | |||
/** | |||
* 根据第三方授权验证token 进行获取用户信息并跳转相关地址 | |||
@@ -57,12 +54,23 @@ public class ThirdServiceImpl implements ThirdService { | |||
*/ | |||
@Override | |||
public JsonResult authorize(String clientId) { | |||
String username; | |||
String password; | |||
if(ThirdConstant.TUOHENG_AIRPORT_ADMIN.equals(clientId)){ | |||
username = ThirdConstant.GZJJ_USERNAME; | |||
password = ThirdConstant.GZJJ_PASSWORD; | |||
}else if(ThirdConstant.TUOHENG_TELECOMUMALE_ADMIN.equals(clientId)){ | |||
username = ThirdConstant.HLCG_USERNAME; | |||
password = ThirdConstant.HLCG_PASSWORD; | |||
}else { | |||
return JsonResult.error("clientId error"); | |||
} | |||
//通过oidc的密码模式获取授权token 等相关信息数据 | |||
TokenResult tokenResult = getToken(clientId); | |||
TokenResult tokenResult = getToken(clientId,username,password); | |||
tokenResult.setUserName(username); | |||
//此时通过token获取当前用户的相关权限信息并进行封装 | |||
tokenResult = getClientResult(tokenResult, clientId); | |||
tokenResult = getClientResult(tokenResult, clientId, username); | |||
//数据封装完毕返回数据 以及相关地址 -> 是否重定向 | |||
return JsonResult.success(tokenResult); | |||
} | |||
@@ -70,7 +78,7 @@ public class ThirdServiceImpl implements ThirdService { | |||
/** | |||
* 通过账号密码获取token | |||
*/ | |||
private TokenResult getToken(String clientId) { | |||
private TokenResult getToken(String clientId, String username, String password) { | |||
RegisteredClientPo clientPo = registeredClientMapper.selectClient(clientId); | |||
if (ObjectUtils.isEmpty(clientPo)) { | |||
@@ -108,7 +116,7 @@ public class ThirdServiceImpl implements ThirdService { | |||
* @param tokenResult | |||
* @return | |||
*/ | |||
private TokenResult getClientResult(TokenResult tokenResult, String clientId) { | |||
private TokenResult getClientResult(TokenResult tokenResult, String clientId, String username) { | |||
String url = tokenIssuer + OidcConstant.GET_USERINFO; | |||
@@ -1,62 +0,0 @@ | |||
spring: | |||
security: | |||
oauth2: | |||
resource-server: | |||
jwt: | |||
issuer-uri: http://192.168.11.11:8090 #认证中心端点,作为资源端的配置 | |||
#issuer-uri: http://oidc.dev.t-aaron.com | |||
# 配置数据源 | |||
datasource: | |||
# 使用阿里的Druid连接池 | |||
type: com.alibaba.druid.pool.DruidDataSource | |||
driver-class-name: com.mysql.cj.jdbc.Driver | |||
# 填写你数据库的url、登录名、密码和数据库名 | |||
url: jdbc:mysql://192.168.11.13:3306/tuoheng_oidc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false | |||
username: root | |||
password: idontcare | |||
druid: | |||
# 连接池的配置信息 | |||
# 初始连接数 | |||
initialSize: 5 | |||
# 最小连接池数量 | |||
minIdle: 5 | |||
# 最大连接池数量 | |||
maxActive: 20 | |||
# 配置获取连接等待超时的时间 | |||
maxWait: 60000 | |||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||
timeBetweenEvictionRunsMillis: 60000 | |||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||
minEvictableIdleTimeMillis: 300000 | |||
# 配置一个连接在池中最大生存的时间,单位是毫秒 | |||
maxEvictableIdleTimeMillis: 900000 | |||
# 配置检测连接是否有效 | |||
validationQuery: SELECT 1 FROM DUAL | |||
testWhileIdle: true | |||
testOnBorrow: false | |||
testOnReturn: false | |||
# Redis数据源 | |||
redis: | |||
# 缓存库默认索引0 | |||
database: 0 | |||
# Redis服务器地址 | |||
host: 192.168.11.13 | |||
# Redis服务器连接端口 | |||
port: 6379 | |||
# Redis服务器连接密码(默认为空) | |||
password: | |||
# 连接超时时间(毫秒) | |||
timeout: 6000 | |||
# 默认的数据过期时间,主要用于shiro权限管理 | |||
expire: 2592000 | |||
jedis: | |||
pool: | |||
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) | |||
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-idle: 10 # 连接池中的最大空闲连接 | |||
min-idle: 1 # 连接池中的最小空闲连接 | |||
oauth2: | |||
token: | |||
issuer: http://192.168.11.11:8090 |
@@ -1,60 +0,0 @@ | |||
spring: | |||
security: | |||
oauth2: | |||
resource-server: | |||
jwt: | |||
issuer-uri: http://127.0.0.1:8090 #认证中心端点,作为资源端的配置、 | |||
# 配置数据源 | |||
datasource: | |||
# 使用阿里的Druid连接池 | |||
type: com.alibaba.druid.pool.DruidDataSource | |||
driver-class-name: com.mysql.cj.jdbc.Driver | |||
# 填写你数据库的url、登录名、密码和数据库名 | |||
url: jdbc:mysql://192.168.11.13:3306/tuoheng_oidc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false | |||
username: root | |||
password: idontcare | |||
druid: | |||
# 连接池的配置信息 | |||
# 初始连接数 | |||
initialSize: 5 | |||
# 最小连接池数量 | |||
minIdle: 5 | |||
# 最大连接池数量 | |||
maxActive: 20 | |||
# 配置获取连接等待超时的时间 | |||
maxWait: 60000 | |||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||
timeBetweenEvictionRunsMillis: 60000 | |||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||
minEvictableIdleTimeMillis: 300000 | |||
# 配置一个连接在池中最大生存的时间,单位是毫秒 | |||
maxEvictableIdleTimeMillis: 900000 | |||
# 配置检测连接是否有效 | |||
validationQuery: SELECT 1 FROM DUAL | |||
testWhileIdle: true | |||
testOnBorrow: false | |||
testOnReturn: false | |||
# Redis数据源 | |||
redis: | |||
# 缓存库默认索引0 | |||
database: 0 | |||
# Redis服务器地址 | |||
host: 192.168.11.13 | |||
# Redis服务器连接端口 | |||
port: 6379 | |||
# Redis服务器连接密码(默认为空) | |||
password: | |||
# 连接超时时间(毫秒) | |||
timeout: 6000 | |||
# 默认的数据过期时间,主要用于shiro权限管理 | |||
expire: 2592000 | |||
jedis: | |||
pool: | |||
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) | |||
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-idle: 10 # 连接池中的最大空闲连接 | |||
min-idle: 1 # 连接池中的最小空闲连接 | |||
oauth2: | |||
token: | |||
issuer: http://127.0.0.1:8090 |
@@ -1,60 +0,0 @@ | |||
spring: | |||
security: | |||
oauth2: | |||
resource-server: | |||
jwt: | |||
issuer-uri: https://oidc.t-aaron.com #认证中心端点,作为资源端的配置、 | |||
# 配置数据源 | |||
datasource: | |||
# 使用阿里的Druid连接池 | |||
type: com.alibaba.druid.pool.DruidDataSource | |||
driver-class-name: com.mysql.cj.jdbc.Driver | |||
# 填写你数据库的url、登录名、密码和数据库名 | |||
url: jdbc:mysql://rm-uf6x76i111rb1eo48.mysql.rds.aliyuncs.com:3306/tuoheng_oidc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false | |||
username: root | |||
password: TH22#2022 | |||
druid: | |||
# 连接池的配置信息 | |||
# 初始连接数 | |||
initialSize: 5 | |||
# 最小连接池数量 | |||
minIdle: 5 | |||
# 最大连接池数量 | |||
maxActive: 20 | |||
# 配置获取连接等待超时的时间 | |||
maxWait: 60000 | |||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||
timeBetweenEvictionRunsMillis: 60000 | |||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||
minEvictableIdleTimeMillis: 300000 | |||
# 配置一个连接在池中最大生存的时间,单位是毫秒 | |||
maxEvictableIdleTimeMillis: 900000 | |||
# 配置检测连接是否有效 | |||
validationQuery: SELECT 1 FROM DUAL | |||
testWhileIdle: true | |||
testOnBorrow: false | |||
testOnReturn: false | |||
# Redis数据源 | |||
redis: | |||
# 缓存库默认索引0 | |||
database: 0 | |||
# Redis服务器地址 | |||
host: r-uf6r5lm7c7sfdv3ehb.redis.rds.aliyuncs.com | |||
# Redis服务器连接端口 | |||
port: 6379 | |||
# Redis服务器连接密码(默认为空) | |||
password: | |||
# 连接超时时间(毫秒) | |||
timeout: 6000 | |||
# 默认的数据过期时间,主要用于shiro权限管理 | |||
expire: 2592000 | |||
jedis: | |||
pool: | |||
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) | |||
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-idle: 10 # 连接池中的最大空闲连接 | |||
min-idle: 1 # 连接池中的最小空闲连接 | |||
oauth2: | |||
token: | |||
issuer: https://oidc.t-aaron.com |
@@ -1,61 +0,0 @@ | |||
spring: | |||
security: | |||
oauth2: | |||
resource-server: | |||
jwt: | |||
#issuer-uri: http://192.168.11.241:8090 #认证中心端点,作为资源端的配置、 | |||
issuer-uri: https://login-test.t-aaron.com #认证中心端点,作为资源端的配置、 | |||
# 配置数据源 | |||
datasource: | |||
# 使用阿里的Druid连接池 | |||
type: com.alibaba.druid.pool.DruidDataSource | |||
driver-class-name: com.mysql.cj.jdbc.Driver | |||
# 填写你数据库的url、登录名、密码和数据库名 | |||
url: jdbc:mysql://rm-uf6z740323e8053pj.mysql.rds.aliyuncs.com:3306/tuoheng_oidc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false | |||
username: root | |||
password: TH22#2022 | |||
druid: | |||
# 连接池的配置信息 | |||
# 初始连接数 | |||
initialSize: 5 | |||
# 最小连接池数量 | |||
minIdle: 5 | |||
# 最大连接池数量 | |||
maxActive: 20 | |||
# 配置获取连接等待超时的时间 | |||
maxWait: 60000 | |||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||
timeBetweenEvictionRunsMillis: 60000 | |||
# 配置一个连接在池中最小生存的时间,单位是毫秒 | |||
minEvictableIdleTimeMillis: 300000 | |||
# 配置一个连接在池中最大生存的时间,单位是毫秒 | |||
maxEvictableIdleTimeMillis: 900000 | |||
# 配置检测连接是否有效 | |||
validationQuery: SELECT 1 FROM DUAL | |||
testWhileIdle: true | |||
testOnBorrow: false | |||
testOnReturn: false | |||
# Redis数据源 | |||
redis: | |||
# 缓存库默认索引0 | |||
database: 0 | |||
# Redis服务器地址 | |||
host: r-uf6cdzjifj20jszykr.redis.rds.aliyuncs.com | |||
# Redis服务器连接端口 | |||
port: 6379 | |||
# Redis服务器连接密码(默认为空) | |||
password: | |||
# 连接超时时间(毫秒) | |||
timeout: 6000 | |||
# 默认的数据过期时间,主要用于shiro权限管理 | |||
expire: 2592000 | |||
jedis: | |||
pool: | |||
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) | |||
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-idle: 10 # 连接池中的最大空闲连接 | |||
min-idle: 1 # 连接池中的最小空闲连接 | |||
oauth2: | |||
token: | |||
issuer: https://login-test.t-aaron.com |
@@ -1,12 +0,0 @@ | |||
server: | |||
port: 8090 | |||
spring: | |||
profiles: | |||
active: dev | |||
web: | |||
resources: | |||
static-locations: classpath:/ | |||
mybatis: | |||
mapper-locations: classpath*:mapper/*Mapper.xml |
@@ -1,69 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --> | |||
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true --> | |||
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。 | |||
当scan为true时,此属性生效。默认的时间间隔为1分钟。 --> | |||
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> | |||
<configuration scan="true" scanPeriod="60 seconds" debug="false"> | |||
<!-- | |||
contextName说明: | |||
每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用设置成其他名字, | |||
用于区分不同应用程序的记录。一旦设置,不能修改,可以通过%contextName来打印日志上下文名称。 | |||
--> | |||
<contextName>tuoheng_oidc_server</contextName> | |||
<!--定义日志变量--> | |||
<!--<property name="logging.path" value="D:\\idealogs\\tuoheng_oidc"/>--> | |||
<property name="logging.path" value="/data/java/logs/tuoheng_oidc"/> | |||
<!--日志格式: [时间] [级别] [线程] [行号] [logger信息] - [日志信息]--> | |||
<property name="logging.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%level][%thread][%L] %logger - %msg%n"/> | |||
<property name="logging.charset" value="UTF-8"/> | |||
<property name="logging.maxHistory" value="15"/> | |||
<property name="logging.totalSizeCap" value="5GB"/> | |||
<property name="logging.maxFileSize" value="40MB"/> | |||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> | |||
<encoder> | |||
<pattern>${logging.pattern}</pattern> | |||
<charset>${logging.charset}</charset> | |||
</encoder> | |||
</appender> | |||
<appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
<File>${logging.path}/server/tuoheng_oidc_server.log</File> | |||
<append>true</append> | |||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | |||
<fileNamePattern>${logging.path}/server/tuoheng_oidc_server-%d-%i.log</fileNamePattern> | |||
<!-- 最大保存天数--> | |||
<maxHistory>${logging.maxHistory}</maxHistory> | |||
<totalSizeCap>${logging.totalSizeCap}</totalSizeCap> | |||
<maxFileSize>${logging.maxFileSize}</maxFileSize> | |||
</rollingPolicy> | |||
<!--编码器--> | |||
<encoder> | |||
<pattern>${logging.pattern}</pattern> | |||
<charset>${logging.charset}</charset> | |||
</encoder> | |||
</appender> | |||
<appender name="file.async" class="ch.qos.logback.classic.AsyncAppender"> | |||
<discardingThreshold>0</discardingThreshold> | |||
<queueSize>512</queueSize> | |||
<includeCallerData>true</includeCallerData> | |||
<appender-ref ref="LOG_FILE" /> | |||
</appender> | |||
<logger name="com.tuoheng" level="DEBUG" additivity="false"> | |||
<appender-ref ref="console" /> | |||
<appender-ref ref="file.async" /> | |||
</logger> | |||
<!--log4jdbc --> | |||
<logger name="jdbc.sqltiming" level="DEBUG" additivity="false"> | |||
<appender-ref ref="file.async" /> | |||
</logger> | |||
<root level="INFO"> | |||
<appender-ref ref="console" /> | |||
<appender-ref ref="file.async" /> | |||
</root> | |||
</configuration> |
@@ -1,13 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="com.tuoheng.mapper.AuthoritiesMapper"> | |||
<insert id="batchInsert" parameterType="java.util.List"> | |||
insert into authorities (user_id, username, authority) | |||
VALUES | |||
<foreach collection ="list" item="it" separator =","> | |||
(#{it.userId}, #{it.username}, #{it.authority}) | |||
</foreach > | |||
</insert> | |||
</mapper> |
@@ -1,55 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="com.tuoheng.mapper.UserMapper"> | |||
<resultMap type="com.tuoheng.model.dto.UserBaseInfoDto" id="UserBaseInfoMap"> | |||
<id column="userId" jdbcType="INTEGER" property="userId"/> | |||
<result column="userName" jdbcType="VARCHAR" property="userName"/> | |||
<result column="password" jdbcType="VARCHAR" property="password"/> | |||
<result column="isAble" jdbcType="INTEGER" property="isAble"/> | |||
<result column="isExpire" jdbcType="INTEGER" property="isExpire"/> | |||
<collection property="authorityList" ofType="java.lang.String" javaType="java.util.List"> | |||
<result column="authority" jdbcType="VARCHAR"/> | |||
</collection> | |||
<collection property="clientRoleDtoList" ofType="com.tuoheng.model.dto.ClientRoleDto" javaType="java.util.List"> | |||
<result column="clientId" jdbcType="VARCHAR" property="clientId"/> | |||
<result column="roleId" jdbcType="INTEGER" property="roleId"/> | |||
</collection> | |||
</resultMap> | |||
<insert id="insertUser" parameterType="com.tuoheng.model.po.UserPo" keyProperty="id" useGeneratedKeys="true"> | |||
insert into users (username, password) | |||
values (#{username}, #{password}) | |||
</insert> | |||
<select id="getUserBaseInfo" resultMap="UserBaseInfoMap"> | |||
select a.id as userId, | |||
a.username as userName, | |||
a.password, | |||
b.authority, | |||
c.client_id as clientId, | |||
c.role_id as roleId, | |||
a.is_able as isAble, | |||
a.is_expire as isExpire | |||
from users a | |||
left join authorities b on a.id = b.user_id | |||
left join t_client_user_role c on a.id = c.user_id | |||
where a.username = #{username} | |||
</select> | |||
<select id="getMpUserInfo" resultMap="UserBaseInfoMap"> | |||
select a.id as userId, | |||
a.username as userName, | |||
a.password, | |||
b.authority, | |||
c.client_id as clientId, | |||
c.role_id as roleId, | |||
a.is_able as isAble, | |||
a.is_expire as isExpire | |||
from users a | |||
left join authorities b on a.id = b.user_id | |||
left join t_client_user_role c on a.id = c.user_id | |||
where a.username = #{username} | |||
</select> | |||
</mapper> |
@@ -1,206 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>登录页面</title> | |||
</head> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||
<title>login</title> | |||
<script src="../static/jquery-3.5.1.min.js"></script> | |||
<style> | |||
.login__back{ | |||
position: fixed; | |||
top: 0; | |||
right: 0; | |||
bottom: 0; | |||
left: 0; | |||
background: url('../static/back.png'); | |||
background-position: center center; | |||
background-repeat: no-repeat; | |||
background-attachment: fixed; | |||
background-size: cover; | |||
} | |||
.login__form{ | |||
/* width: 460px; | |||
height: 410px; */ | |||
width: 410px; | |||
height: 350px; | |||
background: url('../static/form.png'); | |||
background-position: center center; | |||
background-repeat: no-repeat; | |||
background-size: cover; | |||
padding: 60px 30px; | |||
color: rgba(255, 255, 255, 1); | |||
position: relative; | |||
left: 50%; | |||
top: 50%; | |||
transform: translate(-50%,-50%); | |||
} | |||
.login__form h2{ | |||
font-size: 28px; | |||
line-height: 25px; | |||
text-align: center; | |||
margin-bottom: 10px; | |||
} | |||
.login__form p{ | |||
font-size: 12px; | |||
text-align: center; | |||
margin-bottom: 36px; | |||
} | |||
.login__form form{ | |||
padding: 0 40px; | |||
display: flex; | |||
flex-direction: column; | |||
background: transparent; | |||
position: relative; | |||
} | |||
form input{ | |||
height: 40px; | |||
margin-bottom: 18px; | |||
border-radius: 6px; | |||
color: #FFFFFF; | |||
padding: 0 16px; | |||
border: 1px solid rgba(255, 255, 255, 0.5); | |||
background: transparent; | |||
} | |||
form input:focus-within{ | |||
outline: 0; | |||
border: 1px solid #08EBFE; | |||
} | |||
button{ | |||
height: 46px; | |||
border: none; | |||
border-radius: 6px; | |||
background: linear-gradient(0deg, #08EBFE 0%, #28BAC1 100%); | |||
margin-top: 20px; | |||
color: #FFFFFF; | |||
font-size: 16px; | |||
} | |||
.form__code{ | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
margin-bottom: 18px; | |||
} | |||
.form__code input{ | |||
width: calc(100% - 152px); | |||
margin-bottom: 0; | |||
} | |||
.form__code img{ | |||
width: 100px; | |||
height: 42px; | |||
cursor: pointer; | |||
} | |||
.login__form .form__tips{ | |||
margin: 0; | |||
height: 0; | |||
position: relative; | |||
top: -14px; | |||
} | |||
.form__tips.is--error{ | |||
color: red | |||
} | |||
/* 密码框显示隐藏图表 */ | |||
#close_eyes, #open_eyes{ | |||
width: 18px; | |||
height: 18px; | |||
position: absolute; | |||
right: 50px; | |||
top: 72px; | |||
} | |||
#open_eyes { | |||
display: none; | |||
} | |||
</style> | |||
</head> | |||
<body> | |||
<div class="login__back"> | |||
<div class="login__form"> | |||
<h2>统一登录平台</h2> | |||
<p>LOGIN PLATFORM</p> | |||
<form th:action="@{/login}" method="post"> | |||
<input name="username" placeholder="请输入用户名" type="text"/> | |||
<input id="password" name="password" placeholder="请输入密码" type="password"/> | |||
<!-- 密码显示隐藏 --> | |||
<img src="../static/close.png" alt="" id="close_eyes"> | |||
<img src="../static/open.png" alt="" id="open_eyes"> | |||
<div class="form__code"> | |||
<input name="validateCode" placeholder="请输入验证码" /> | |||
<input id="codekey" name="codekey" type="hidden"/> | |||
<img class="code__img" src="" /> | |||
</div> | |||
<div class="form__tips is--error" th:if="${param.error}"> | |||
用户名密码错误,请重新输入! | |||
</div> | |||
<div class="form__tips is--error" th:if="${param.validerror}"> | |||
验证码错误,请重新输入! | |||
</div> | |||
<div class="form__tips is--error" th:if="${param.expirecode}"> | |||
验证码已过期,请重新输入! | |||
</div> | |||
<button type="submit">登 录</button> | |||
</form> | |||
</div> | |||
</div> | |||
<!--绑定点击事件 --> | |||
<script> | |||
const imgDom = document.querySelector('.code__img') | |||
imgDom.onclick = function() { | |||
$.ajax({ | |||
url : "/vercode",//后台请求的数据 | |||
dataType: 'json', //数据格式 | |||
type : "post",//请求方式 | |||
async : true,//是否异步请求 | |||
success : function(data) { //如果请求成功,返回数据。 | |||
var tt = data.data; //第一个data代表json,第二个data代表json里的数组或对象 | |||
$('.code__img').attr('src', tt.captcha); | |||
$('#codekey').val(tt.codeKey); | |||
}, | |||
error : function (arg1) { | |||
alert("加载数据失败"); | |||
console.log(arg1); | |||
} | |||
}) | |||
} | |||
// 密码显示隐藏 | |||
const passwordDom = document.getElementById('password') | |||
const openIcon = document.getElementById('open_eyes') | |||
const closeIcon = document.getElementById('close_eyes') | |||
closeIcon.onclick = function() { | |||
passwordDom.type = 'text' | |||
openIcon.style.display = 'block' | |||
closeIcon.style.display = 'none' | |||
} | |||
openIcon.onclick = function() { | |||
passwordDom.type = 'password' | |||
openIcon.style.display = 'none' | |||
closeIcon.style.display = 'block' | |||
} | |||
$(document).ready(function() { | |||
$.ajax({ | |||
url : "/vercode",//后台请求的数据 | |||
dataType: 'json', //数据格式 | |||
type : "post",//请求方式 | |||
async : true,//是否异步请求 | |||
success : function(data) { //如果请求成功,返回数据。 | |||
var tt = data.data; //第一个data代表json,第二个data代表json里的数组或对象 | |||
$('.code__img').attr('src', tt.captcha); | |||
$('#codekey').val(tt.codeKey); | |||
}, | |||
error : function (arg1) { | |||
alert("加载数据失败"); | |||
console.log(arg1); | |||
} | |||
}) | |||
}) | |||
</script> | |||
</body> | |||
</html> |