From 91b924bdc187e0eb5170917c99c33bc6e5ca7dd8 Mon Sep 17 00:00:00 2001 From: wangping Date: Wed, 4 Nov 2020 11:58:36 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E5=BC=80=E6=94=BE=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E6=8E=A5=E5=8F=A3=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 3 +- sop-openapi/pom.xml | 110 ++++++++++++++++++ .../sop/openapi/SopOpenapiApplication.java | 8 ++ .../sop/openapi/config/OpenapiConfig.java | 33 ++++++ .../gitee/sop/openapi/config/RedisConfig.java | 43 +++++++ .../sop/openapi/config/RedisOperator.java | 80 +++++++++++++ .../controller/AuthCodeController.java | 39 +++++++ .../controller/AuthTokenController.java | 27 +++++ .../openapi/entity/IsvAuthTokenEntity.java | 37 ++++++ .../sop/openapi/entity/IsvInfoEntity.java | 30 +++++ .../openapi/mapper/IsvAuthTokenMapper.java | 11 ++ .../sop/openapi/mapper/IsvInfoMapper.java | 11 ++ .../com/gitee/sop/openapi/po/AuthCodePo.java | 26 +++++ .../com/gitee/sop/openapi/po/AuthTokePo.java | 46 ++++++++ .../sop/openapi/service/AuthCodeService.java | 106 +++++++++++++++++ .../gitee/sop/openapi/util/AuthErrorEnum.java | 10 ++ .../gitee/sop/openapi/util/LogFormatUtil.java | 27 +++++ .../sop/openapi/util/MD5GeneratorUtil.java | 53 +++++++++ .../gitee/sop/openapi/util/RedisKeyUtil.java | 30 +++++ .../com/gitee/sop/openapi/vo/AuthCodeVo.java | 9 ++ .../main/resources/application-cluster.yml | 16 +++ .../main/resources/application-sentinel.yml | 16 +++ .../main/resources/application-standalone.yml | 13 +++ .../src/main/resources/application.properties | 6 + .../resources/isp/auth_error_en.properties | 4 + .../resources/isp/auth_error_zh_CN.properties | 9 ++ .../main/resources/isp/bizerror_en.properties | 5 + .../resources/isp/bizerror_zh_CN.properties | 9 ++ .../src/test/java/com/gitee/sop/AppTest.java | 20 ++++ 29 files changed, 836 insertions(+), 1 deletion(-) create mode 100644 sop-openapi/pom.xml create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/SopOpenapiApplication.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/config/OpenapiConfig.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/config/RedisConfig.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/config/RedisOperator.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthCodeController.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthTokenController.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvInfoEntity.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvAuthTokenMapper.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvInfoMapper.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthCodePo.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthTokePo.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/util/AuthErrorEnum.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/util/LogFormatUtil.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/util/MD5GeneratorUtil.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/util/RedisKeyUtil.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/vo/AuthCodeVo.java create mode 100644 sop-openapi/src/main/resources/application-cluster.yml create mode 100644 sop-openapi/src/main/resources/application-sentinel.yml create mode 100644 sop-openapi/src/main/resources/application-standalone.yml create mode 100644 sop-openapi/src/main/resources/application.properties create mode 100644 sop-openapi/src/main/resources/isp/auth_error_en.properties create mode 100644 sop-openapi/src/main/resources/isp/auth_error_zh_CN.properties create mode 100644 sop-openapi/src/main/resources/isp/bizerror_en.properties create mode 100644 sop-openapi/src/main/resources/isp/bizerror_zh_CN.properties create mode 100644 sop-openapi/src/test/java/com/gitee/sop/AppTest.java diff --git a/pom.xml b/pom.xml index 6cdbeb88..6d7b000f 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,8 @@ sop-test sop-sdk sop-website - + sop-openapi + 1.8 diff --git a/sop-openapi/pom.xml b/sop-openapi/pom.xml new file mode 100644 index 00000000..1f74e3c7 --- /dev/null +++ b/sop-openapi/pom.xml @@ -0,0 +1,110 @@ + + + + 4.0.0 + + com.gitee.sop + sop-parent + 4.0.3-SNAPSHOT + ../pom.xml + + com.gitee.sop.openapi + sop-openapi + sop-openapi + + + + com.gitee.sop + sop-service-common + 4.0.3-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + com.github.xiaoymin + swagger-bootstrap-ui + 1.9.5 + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.apache.commons + commons-lang3 + + + + mysql + mysql-connector-java + runtime + + + + net.oschina.durcframework + fastmybatis-spring-boot-starter + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12.4 + + true + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/SopOpenapiApplication.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/SopOpenapiApplication.java new file mode 100644 index 00000000..c3479299 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/SopOpenapiApplication.java @@ -0,0 +1,8 @@ +package com.gitee.sop.openapi; + +public class SopOpenapiApplication { + + public static void main(String[] args) { + + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/config/OpenapiConfig.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/config/OpenapiConfig.java new file mode 100644 index 00000000..a0a597fa --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/config/OpenapiConfig.java @@ -0,0 +1,33 @@ +package com.gitee.sop.openapi.config; + +import com.gitee.sop.servercommon.bean.ServiceConfig; +import com.gitee.sop.servercommon.swagger.SwaggerSupport; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +public class OpenapiConfig { + + static { + ServiceConfig.getInstance().getI18nModules().add("i18n/isp/auth_error"); + } + + + /** + * 开启文档,本地微服务文档地址:http://localhost:2222/doc.html + * http://ip:port/v2/api-docs + */ + @Configuration + @EnableSwagger2 + public static class Swagger2 extends SwaggerSupport { + @Override + protected String getDocTitle() { + return "开放平台API"; + } + + @Override + protected boolean swaggerAccessProtected() { + return false; + } + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/config/RedisConfig.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/config/RedisConfig.java new file mode 100644 index 00000000..84b6b23b --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/config/RedisConfig.java @@ -0,0 +1,43 @@ +package com.gitee.sop.openapi.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + + @Bean + public RedisTemplate redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory) { + + RedisTemplate redisTemplate = new RedisTemplate(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(objectMapper); + + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + + // key采用String的序列化方式 + redisTemplate.setKeySerializer(stringRedisSerializer); + // hash的key也采用String的序列化方式 + redisTemplate.setHashKeySerializer(stringRedisSerializer); + // value采用jackson序列化方式 + redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); + // hash的value采用jackson序列化方式 + redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/config/RedisOperator.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/config/RedisOperator.java new file mode 100644 index 00000000..862b0afa --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/config/RedisOperator.java @@ -0,0 +1,80 @@ +package com.gitee.sop.openapi.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/*** + * + * @author wangping created on 2020/11/2 17:22 + */ +@Slf4j +@Component +public class RedisOperator { + + private final RedisTemplate redisTemplate; + + public RedisOperator(final RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + public boolean expire(String key, long time) { + try { + if (time >= 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + log.error("redisTemplate.expire.Error", e); + return false; + } + } + + + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + log.error("redisTemplate.set.Error", e); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error("redisTemplate.setAndExpire.Error", e); + return false; + } + } + + + public boolean del(String key) { + return redisTemplate.delete(key); + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthCodeController.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthCodeController.java new file mode 100644 index 00000000..3e7b3c55 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthCodeController.java @@ -0,0 +1,39 @@ +package com.gitee.sop.openapi.controller; + +import com.gitee.sop.openapi.po.AuthCodePo; +import com.gitee.sop.openapi.vo.AuthCodeVo; +import com.gitee.sop.openapi.service.AuthCodeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotBlank; + +@Slf4j +@RestController +@Api(tags = "超浏授权接口") +public class AuthCodeController { + + + private final AuthCodeService authCodeService; + + public AuthCodeController(final AuthCodeService authCodeService) { + this.authCodeService = authCodeService; + } + + + @ApiOperation(value = "获取code") + @PostMapping("/auth/code") + public AuthCodeVo getCode(@RequestBody AuthCodePo authCodePo) { + return authCodeService.getCode(authCodePo); + } + + + @ApiOperation(value = "解除授权") + @PostMapping("/auth/cancel") + public void cancelToken(@NotBlank(message = "{isp.auth.user_id_empty_error}") Long userId) { + authCodeService.cancelToken(userId); + } + +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthTokenController.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthTokenController.java new file mode 100644 index 00000000..68330c9e --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthTokenController.java @@ -0,0 +1,27 @@ +package com.gitee.sop.openapi.controller; + +import com.gitee.sop.openapi.po.AuthTokePo; +import com.gitee.sop.servercommon.annotation.Open; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@Api(tags = "插件应用获取token接口") +public class AuthTokenController { + + + + @Open(value = "auth.get.token", ignoreValidate = true, mergeResult = false, needToken = false) + @PostMapping(value = "/token") + @ApiOperation(value = "code换token", notes = "插件服务器获取token") + public String getToken(@RequestBody AuthTokePo tokePo) { + + + return ""; + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java new file mode 100644 index 00000000..011b4ea3 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java @@ -0,0 +1,37 @@ +package com.gitee.sop.openapi.entity; + +import lombok.Data; +import org.springframework.data.annotation.Id; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Table; + +/*** + * + * @author wangping created on 2020/11/2 16:57 + */ + +@Data +@Table(name = "isv_auth_token") +public class IsvAuthTokenEntity { + + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + /** 数据库字段:id */ + private Long id; + + /** appKey, 数据库字段:app_key */ + private String appKey; + + /** userId, 数据库字段:user_id */ + private Long userId; + + /** 1启用,2禁用, 数据库字段:status */ + private Byte status; + + /** appAuthToken 数据库字段:app_auth_token */ + private String appAuthToken; +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvInfoEntity.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvInfoEntity.java new file mode 100644 index 00000000..a20d384a --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvInfoEntity.java @@ -0,0 +1,30 @@ +package com.gitee.sop.openapi.entity; + +import lombok.Data; +import org.springframework.data.annotation.Id; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Table; + +/*** + * + * @author wangping created on 2020/11/2 16:22 + */ +@Data +@Table(name = "isv_info") +public class IsvInfoEntity { + + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + /** 数据库字段:id */ + private Long id; + + /** appKey, 数据库字段:app_key */ + private String appKey; + + /** 1启用,2禁用, 数据库字段:status */ + private Byte status; +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvAuthTokenMapper.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvAuthTokenMapper.java new file mode 100644 index 00000000..eda698cf --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvAuthTokenMapper.java @@ -0,0 +1,11 @@ +package com.gitee.sop.openapi.mapper; + +import com.gitee.fastmybatis.core.mapper.CrudMapper; +import com.gitee.sop.openapi.entity.IsvAuthTokenEntity; + +/*** + * + * @author wangping created on 2020/11/2 16:59 + */ +public interface IsvAuthTokenMapper extends CrudMapper { +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvInfoMapper.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvInfoMapper.java new file mode 100644 index 00000000..46bc108d --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvInfoMapper.java @@ -0,0 +1,11 @@ +package com.gitee.sop.openapi.mapper; + +import com.gitee.fastmybatis.core.mapper.CrudMapper; +import com.gitee.sop.openapi.entity.IsvInfoEntity; + +/*** + * + * @author wangping created on 2020/11/2 15:52 + */ +public interface IsvInfoMapper extends CrudMapper { +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthCodePo.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthCodePo.java new file mode 100644 index 00000000..54211c81 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthCodePo.java @@ -0,0 +1,26 @@ +package com.gitee.sop.openapi.po; + +import com.gitee.sop.servercommon.param.validation.Group1; +import com.gitee.sop.servercommon.param.validation.Group2; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + + +@Data +public class AuthCodePo { + + + @ApiModelProperty(value = "应用ID", required = true, example = "test1", position = 1) + @NotBlank(message = "{isp.auth.app_id_empty_error}", groups = Group1.class) + @Length(min = 1, max = 64, message = "{isp.auth.app_id_length_error}=1,64", groups = Group2.class) + private String appId; + + @ApiModelProperty(value = "用户ID", required = true, example = "1", position = 2) + @NotNull(message = "{isp.auth.user_id_empty_error}") + private Long userId; + +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthTokePo.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthTokePo.java new file mode 100644 index 00000000..446dbcb8 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthTokePo.java @@ -0,0 +1,46 @@ +package com.gitee.sop.openapi.po; + +import com.gitee.sop.servercommon.param.validation.Group1; +import com.gitee.sop.servercommon.param.validation.Group2; +import io.swagger.annotations.ApiModelProperty; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/*** + * + * @author wangping created on 2020/11/2 18:31 + */ +public class AuthTokePo { + + + + /** + * 授权码.与refresh_token二选一,用户对应用授权后得到,即第一步中开发者获取到的app_auth_code值 + */ + @ApiModelProperty(value = "应用ID", example = "test1", position = 1) + @NotBlank(message = "{isp.auth.app_id_empty_error}", groups = Group1.class) + @Length(min = 1, max = 64, message = "{isp.auth.app_id_length_error}=1,64", groups = Group2.class) + private String code; + + @NotBlank(message = "{isp.auth.user_token_empty_error}", groups = Group1.class) + @Length(min = 1, max = 64, message = "{isp.auth.user_token_length_error}=1,64", groups = Group2.class) + @ApiModelProperty(value = "用户登录凭证", required = true, example = "1111", position = 2) + private String grant_type; + + + /** + * 授权类型。
+ * 如果使用app_auth_code换取token,则为authorization_code, + * 如果使用refresh_token换取新的token,则为refresh_token + */ + @NotBlank(message = "授权类型不能为空") + private String grantType; + + + /** + * 刷新令牌.与code二选一,可为空,刷新令牌时使用 + */ + private String refreshToken; + +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java new file mode 100644 index 00000000..9bb753b4 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java @@ -0,0 +1,106 @@ +package com.gitee.sop.openapi.service; + +import com.gitee.fastmybatis.core.query.Query; +import com.gitee.sop.openapi.config.RedisOperator; +import com.gitee.sop.openapi.entity.IsvAuthTokenEntity; +import com.gitee.sop.openapi.entity.IsvInfoEntity; +import com.gitee.sop.openapi.mapper.IsvAuthTokenMapper; +import com.gitee.sop.openapi.mapper.IsvInfoMapper; +import com.gitee.sop.openapi.po.AuthCodePo; +import com.gitee.sop.openapi.vo.AuthCodeVo; +import com.gitee.sop.openapi.util.MD5GeneratorUtil; +import com.gitee.sop.openapi.util.RedisKeyUtil; +import com.gitee.sop.servercommon.exception.ServiceException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/*** + * + * @author wangping created on 2020/11/2 16:28 + */ +@Slf4j +@Service +public class AuthCodeService { + public static final int FORBIDDEN = 2; + + /** 0 插件应用未授权 **/ + public static final int UNAUTHORIZED = 0; + /** 1 插件应用已授权 **/ + public static final int AUTHORIZED = 1; + + public static final Byte ENABLE_TOKEN = 1; + public static final Byte DISABLE_TOKEN = 0; + + private final IsvInfoMapper isvInfoMapper; + private final IsvAuthTokenMapper isvAuthTokenMapper; + private final RedisOperator redisOperator; + + public AuthCodeService(final IsvInfoMapper isvInfoMapper, + final IsvAuthTokenMapper isvAuthTokenMapper, + final RedisOperator redisOperator) { + this.isvInfoMapper = isvInfoMapper; + this.isvAuthTokenMapper = isvAuthTokenMapper; + this.redisOperator = redisOperator; + } + + public AuthCodeVo getCode(AuthCodePo authCodePo) { + + IsvInfoEntity isvInfo = isvInfoMapper.getByColumn("app_key", authCodePo.getAppId()); + if (isvInfo == null || isvInfo.getStatus().intValue() == FORBIDDEN) { + log.error("appId已禁用:{}", authCodePo.getAppId()); + throw new ServiceException("应用ID未申请或已被禁用"); + } + + // todo check userToken and get userId + + String authCode = MD5GeneratorUtil.generateValue(); + + Query query = new Query() + .eq("app_key", authCodePo.getAppId()) + .eq("user_id", authCodePo.getUserId()) + .eq("status", ENABLE_TOKEN); + IsvAuthTokenEntity authTokenEntity = isvAuthTokenMapper.getByQuery(query); + AuthCodeVo authCodeVo = new AuthCodeVo(); + authCodeVo.setCode(authCode); + if (authTokenEntity == null) { + authCodeVo.setState(UNAUTHORIZED); + authTokenEntity = new IsvAuthTokenEntity(); + authTokenEntity.setAppAuthToken(authCode); + authTokenEntity.setAppKey(authCodePo.getAppId()); + authTokenEntity.setUserId(authCodePo.getUserId()); + isvAuthTokenMapper.save(authTokenEntity); + } else { + authCodeVo.setState(AUTHORIZED); + isvAuthTokenMapper.update(authTokenEntity); + } + + // 写入redis缓存 + String codeKey = RedisKeyUtil.getCodeKey(authCodePo.getAppId(), authCodePo.getUserId()); + redisOperator.set(codeKey, authCodePo.getUserId()); + + return authCodeVo; + } + + + public void cancelToken(Long userId) { + // todo check userToken and get userId + + Query query = new Query() + .eq("user_id", userId) + .eq("status", ENABLE_TOKEN); + + IsvAuthTokenEntity authTokenEntity = isvAuthTokenMapper.getByQuery(query); + if (authTokenEntity == null) { + throw new ServiceException("用户未授权插件应用"); + } + + authTokenEntity.setStatus(ENABLE_TOKEN); + isvAuthTokenMapper.update(authTokenEntity); + + String tokenKey = RedisKeyUtil.getAuthTokenKey(authTokenEntity.getAppKey(), authTokenEntity.getUserId()); + String refreshKey = RedisKeyUtil.getRefreshTokenKey(authTokenEntity.getAppKey(), authTokenEntity.getUserId()); + redisOperator.del(tokenKey); + redisOperator.del(refreshKey); + + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/util/AuthErrorEnum.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/AuthErrorEnum.java new file mode 100644 index 00000000..208eed5d --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/AuthErrorEnum.java @@ -0,0 +1,10 @@ +package com.gitee.sop.openapi.util; + +/*** + * + * @author wangping created on 2020/11/2 16:42 + */ +public enum AuthErrorEnum { + + +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/util/LogFormatUtil.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/LogFormatUtil.java new file mode 100644 index 00000000..001d729c --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/LogFormatUtil.java @@ -0,0 +1,27 @@ +package com.gitee.sop.openapi.util; + +import org.slf4j.helpers.FormattingTuple; +import org.slf4j.helpers.MessageFormatter; + +/*** + * + * @author wangping created on 2020/11/2 18:14 + */ +public class LogFormatUtil { + + /** + * append log with pattern + * + * @param appendLogPattern like "aaa {} bbb {} ccc" + * @param appendLogArguments like "111, true" + */ + public static String log(String appendLogPattern, Object ... appendLogArguments) { + FormattingTuple ft = MessageFormatter.arrayFormat(appendLogPattern, appendLogArguments); + return ft.getMessage(); + } + + + public static void main(String[] args) { + System.out.println(log("My name is {}, from {}", "hanmeimei", "London")); + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/util/MD5GeneratorUtil.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/MD5GeneratorUtil.java new file mode 100644 index 00000000..ff244a5f --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/MD5GeneratorUtil.java @@ -0,0 +1,53 @@ +package com.gitee.sop.openapi.util; + +import com.gitee.sop.servercommon.exception.ServiceException; + +import java.security.MessageDigest; +import java.util.UUID; + +/*** + * + * @author wangping created on 2020/11/2 16:47 + */ +public class MD5GeneratorUtil { + + private static final char[] hexCode = "0123456789abcdef".toCharArray(); + + private MD5GeneratorUtil() { + } + + public static String generateValue() throws ServiceException { + return generateValue(UUID.randomUUID().toString()); + } + + public static String toHexString(byte[] data) { + if (data == null) { + return null; + } else { + StringBuilder r = new StringBuilder(data.length * 2); + byte[] arr$ = data; + int len$ = data.length; + + for (int i$ = 0; i$ < len$; ++i$) { + byte b = arr$[i$]; + r.append(hexCode[b >> 4 & 15]); + r.append(hexCode[b & 15]); + } + + return r.toString(); + } + } + + public static String generateValue(String param) throws ServiceException { + try { + MessageDigest algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(param.getBytes()); + byte[] messageDigest = algorithm.digest(); + return toHexString(messageDigest); + } catch (Exception var4) { + throw new ServiceException("OAuth Token cannot be generated."); + } + } + +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/util/RedisKeyUtil.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/RedisKeyUtil.java new file mode 100644 index 00000000..61ec6687 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/RedisKeyUtil.java @@ -0,0 +1,30 @@ +package com.gitee.sop.openapi.util; + +import com.google.common.base.Joiner; + +/*** + * + * @author wangping created on 2020/11/2 17:47 + */ +public class RedisKeyUtil { + + public static String CODE_PREFIX = "sop:app_auth_code"; + public static String AUTH_TOKEN_PREFIX = "sop:app_auth_token"; + public static String REFRESH_TOKEN_PREFIX = "sop:app_refresh_token"; + + + private static final Joiner JOINER = Joiner.on(":"); + + + public static String getCodeKey(String appId, Long userId) { + return JOINER.join(CODE_PREFIX, appId, userId); + } + + public static String getAuthTokenKey(String appId, Long userId) { + return JOINER.join(AUTH_TOKEN_PREFIX, appId, userId); + } + + public static String getRefreshTokenKey(String appId, Long userId) { + return JOINER.join(REFRESH_TOKEN_PREFIX, appId, userId); + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/vo/AuthCodeVo.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/vo/AuthCodeVo.java new file mode 100644 index 00000000..410e48cc --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/vo/AuthCodeVo.java @@ -0,0 +1,9 @@ +package com.gitee.sop.openapi.vo; + +import lombok.Data; + +@Data +public class AuthCodeVo { + private String code; + private Integer state; +} diff --git a/sop-openapi/src/main/resources/application-cluster.yml b/sop-openapi/src/main/resources/application-cluster.yml new file mode 100644 index 00000000..8f894f6b --- /dev/null +++ b/sop-openapi/src/main/resources/application-cluster.yml @@ -0,0 +1,16 @@ +spring: + redis: + cluster: + nodes: + - 10.1.11.46:7000 + - 10.1.11.46:7001 + - 10.1.11.46:7002 + jedis: + pool: + max-active: 10 + max-wait: -1 + max-idle: 3 + min-idle: 1 + timeout: 60000 + password: + diff --git a/sop-openapi/src/main/resources/application-sentinel.yml b/sop-openapi/src/main/resources/application-sentinel.yml new file mode 100644 index 00000000..bc6419d9 --- /dev/null +++ b/sop-openapi/src/main/resources/application-sentinel.yml @@ -0,0 +1,16 @@ +spring: + redis: + sentinel: + master: mymaster + nodes: + - 192.168.0.114:26379 + - 192.168.0.114:26380 + - 192.168.0.114:26381 + jedis: + pool: + max-active: 10 + max-wait: -1 + max-idle: 9 + min-idle: 0 + timeout: 60000 + password: \ No newline at end of file diff --git a/sop-openapi/src/main/resources/application-standalone.yml b/sop-openapi/src/main/resources/application-standalone.yml new file mode 100644 index 00000000..12b1ea14 --- /dev/null +++ b/sop-openapi/src/main/resources/application-standalone.yml @@ -0,0 +1,13 @@ +spring: + redis: + host: 10.0.0.39 + port: 6379 + jedis: + pool: + max-active: 10 + max-wait: -1 + max-idle: 9 + min-idle: 1 + database: 0 + timeout: 60000 + password: lt@3600 diff --git a/sop-openapi/src/main/resources/application.properties b/sop-openapi/src/main/resources/application.properties new file mode 100644 index 00000000..91aad173 --- /dev/null +++ b/sop-openapi/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.profiles.active=dev + +server.port=8089 +spring.application.name=sop-openapi +# ע +spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 \ No newline at end of file diff --git a/sop-openapi/src/main/resources/isp/auth_error_en.properties b/sop-openapi/src/main/resources/isp/auth_error_en.properties new file mode 100644 index 00000000..53cea47c --- /dev/null +++ b/sop-openapi/src/main/resources/isp/auth_error_en.properties @@ -0,0 +1,4 @@ +isp.auth.user_id_empty_error=the user_id can NOT be null + +isp.auth.app_id_empty_error=the app_id can NOT be null +isp.auth.app_id_length_error=The app_id length must >= {0} and <= {1} \ No newline at end of file diff --git a/sop-openapi/src/main/resources/isp/auth_error_zh_CN.properties b/sop-openapi/src/main/resources/isp/auth_error_zh_CN.properties new file mode 100644 index 00000000..4dae56c3 --- /dev/null +++ b/sop-openapi/src/main/resources/isp/auth_error_zh_CN.properties @@ -0,0 +1,9 @@ +# û¼ƾ֤Ϊ +isp.auth.user_id_empty_error=\u7528\u6237\u0049\u0044\u4e0d\u80fd\u4e3a\u7a7a +# û¼ƾ֤ȱ{0}{1}֮ +#isp.auth.user_token_length_error=\u7528\u6237\u767b\u5f55\u51ed\u8bc1\u957f\u5ea6\u5fc5\u987b\u5728{0}\u548c{1}\u4e4b\u95f4 + +# ӦIDΪ +isp.auth.app_id_empty_error=\u5e94\u7528\u0049\u0044\u4e0d\u80fd\u4e3a\u7a7a +# ӦIDȱ{0}{1}֮ +isp.auth.app_id_length_error=\u5e94\u7528\u0049\u0044\u957f\u5ea6\u5fc5\u987b\u5728{0}\u548c{1}\u4e4b\u95f4 \ No newline at end of file diff --git a/sop-openapi/src/main/resources/isp/bizerror_en.properties b/sop-openapi/src/main/resources/isp/bizerror_en.properties new file mode 100644 index 00000000..8b8a691d --- /dev/null +++ b/sop-openapi/src/main/resources/isp/bizerror_en.properties @@ -0,0 +1,5 @@ +# + +# ϵͳ +isp.error_isv.common-error=The system is busy. +isp.error_isv.invalid-parameter=Invalid parameter, {0} \ No newline at end of file diff --git a/sop-openapi/src/main/resources/isp/bizerror_zh_CN.properties b/sop-openapi/src/main/resources/isp/bizerror_zh_CN.properties new file mode 100644 index 00000000..5df89769 --- /dev/null +++ b/sop-openapi/src/main/resources/isp/bizerror_zh_CN.properties @@ -0,0 +1,9 @@ +# + +# ϵͳæ +isp.error_isv.common-error=\u7cfb\u7edf\u7e41\u5fd9 +# Ч +isp.error_isv.invalid-parameter=\u53c2\u6570\u65e0\u6548, {0} + +# ==== ==== + diff --git a/sop-openapi/src/test/java/com/gitee/sop/AppTest.java b/sop-openapi/src/test/java/com/gitee/sop/AppTest.java new file mode 100644 index 00000000..cbd517a4 --- /dev/null +++ b/sop-openapi/src/test/java/com/gitee/sop/AppTest.java @@ -0,0 +1,20 @@ +package com.gitee.sop; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest +{ + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() + { + assertTrue( true ); + } +} From 21b03137d18a2c396320b4cfb2faaa7755c5af9d Mon Sep 17 00:00:00 2001 From: wangping Date: Wed, 4 Nov 2020 16:26:03 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=E5=BC=80=E6=94=BE=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E8=8E=B7=E5=8F=96token=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-gateway/pom.xml | 10 +++ .../gitee/sop/gateway/config/MyConfig.java | 33 +++++++- .../main/resources/application-dev.properties | 12 ++- sop-openapi/pom.xml | 7 ++ .../sop/openapi/SopOpenapiApplication.java | 8 +- .../openapi/entity/IsvAuthTokenEntity.java | 6 ++ .../com/gitee/sop/openapi/po/AuthTokePo.java | 13 ++- .../sop/openapi/service/AuthCodeService.java | 50 ++++++----- .../sop/openapi/service/AuthService.java | 20 +++++ .../sop/openapi/service/AuthTokenService.java | 83 +++++++++++++++++++ .../com/gitee/sop/openapi/util/GrantType.java | 23 +++++ .../gitee/sop/openapi/util/RedisKeyUtil.java | 12 +-- .../com/gitee/sop/openapi/vo/AuthTokenVo.java | 40 +++++++++ .../main/resources/application-standalone.yml | 4 +- .../src/main/resources/application.properties | 2 +- 15 files changed, 279 insertions(+), 44 deletions(-) create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthService.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthTokenService.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/util/GrantType.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/vo/AuthTokenVo.java diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index 385e8a82..dc4ad9b2 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -67,6 +67,16 @@ 1.18.4 provided + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.apache.commons + commons-lang3 + diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/MyConfig.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/MyConfig.java index 9d32bba9..d9d0475a 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/MyConfig.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/MyConfig.java @@ -1,23 +1,48 @@ package com.gitee.sop.gateway.config; +import com.alibaba.fastjson.JSONObject; import com.gitee.sop.gatewaycommon.bean.ApiConfig; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; +@Slf4j @Component public class MyConfig { + @Autowired + private StringRedisTemplate redisTemplate; + private static String APP_AUTH_TOKEN_PREFIX = "com.gitee.sop.oauth2_access_token:"; + + public static String getAccessTokenKey(String accessToken) { + return APP_AUTH_TOKEN_PREFIX + accessToken; + } + + @PostConstruct public void after() { ApiConfig.getInstance().setTokenValidator(apiParam -> { // 获取客户端传递过来的token - String token = apiParam.fetchAccessToken(); - return !StringUtils.isBlank(token); - // TODO: 校验token有效性,可以从redis中读取 + try { + String token = apiParam.fetchAccessToken(); + if (StringUtils.isBlank(token)) { + return Boolean.FALSE; + } + String json = redisTemplate.opsForValue().get(getAccessTokenKey(token)); + if(StringUtils.isEmpty(json)) { + return Boolean.FALSE; + } - // 返回true表示这个token真实、有效 + JSONObject userInfo = JSONObject.parseObject(json); + return userInfo != null; + } catch (Exception e) { + log.error("redisError", e); + return Boolean.FALSE; + } }); } } \ No newline at end of file diff --git a/sop-gateway/src/main/resources/application-dev.properties b/sop-gateway/src/main/resources/application-dev.properties index 0ba27c4c..e0420b8f 100644 --- a/sop-gateway/src/main/resources/application-dev.properties +++ b/sop-gateway/src/main/resources/application-dev.properties @@ -13,4 +13,14 @@ register.url=127.0.0.1:8848 # 如果需要传输大文本可以把值设置高一点 spring.codec.max-in-memory-size=262144 -logging.level.com.gitee=debug \ No newline at end of file +logging.level.com.gitee=debug + +spring.redis.host=localhost +spring.redis.port=6379 +spring.redis.jedis.pool.min-idle=1 +spring.redis.jedis.pool.max-idle=5 +spring.redis.jedis.pool.max-wait=-1 +spring.redis.jedis.pool.max-active=8 +spring.redis.timeout=60000 +spring.redis.database=0 +spring.redis.password= \ No newline at end of file diff --git a/sop-openapi/pom.xml b/sop-openapi/pom.xml index 1f74e3c7..f035b864 100644 --- a/sop-openapi/pom.xml +++ b/sop-openapi/pom.xml @@ -80,6 +80,13 @@ net.oschina.durcframework fastmybatis-spring-boot-starter + + + org.projectlombok + lombok + 1.18.4 + provided + diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/SopOpenapiApplication.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/SopOpenapiApplication.java index c3479299..29675788 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/SopOpenapiApplication.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/SopOpenapiApplication.java @@ -1,8 +1,14 @@ package com.gitee.sop.openapi; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +@EnableDiscoveryClient +@SpringBootApplication public class SopOpenapiApplication { public static void main(String[] args) { - + SpringApplication.run(SopOpenapiApplication.class, args); } } diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java index 011b4ea3..2fae85fa 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java @@ -32,6 +32,12 @@ public class IsvAuthTokenEntity { /** 1启用,2禁用, 数据库字段:status */ private Byte status; + /** appAuthCode 数据库字段:app_auth_code */ + private String appAuthCode; + /** appAuthToken 数据库字段:app_auth_token */ private String appAuthToken; + + /** appRefreshToken 数据库字段:app_refresh_token */ + private String appRefreshToken; } diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthTokePo.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthTokePo.java index 446dbcb8..e2d88e23 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthTokePo.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/po/AuthTokePo.java @@ -3,6 +3,7 @@ package com.gitee.sop.openapi.po; import com.gitee.sop.servercommon.param.validation.Group1; import com.gitee.sop.servercommon.param.validation.Group2; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotBlank; @@ -11,6 +12,8 @@ import javax.validation.constraints.NotBlank; * * @author wangping created on 2020/11/2 18:31 */ + +@Data public class AuthTokePo { @@ -23,18 +26,14 @@ public class AuthTokePo { @Length(min = 1, max = 64, message = "{isp.auth.app_id_length_error}=1,64", groups = Group2.class) private String code; - @NotBlank(message = "{isp.auth.user_token_empty_error}", groups = Group1.class) - @Length(min = 1, max = 64, message = "{isp.auth.user_token_length_error}=1,64", groups = Group2.class) - @ApiModelProperty(value = "用户登录凭证", required = true, example = "1111", position = 2) - private String grant_type; - - /** * 授权类型。
* 如果使用app_auth_code换取token,则为authorization_code, * 如果使用refresh_token换取新的token,则为refresh_token */ - @NotBlank(message = "授权类型不能为空") + @NotBlank(message = "{isp.auth.user_token_empty_error}", groups = Group1.class) + @Length(min = 1, max = 64, message = "{isp.auth.user_token_length_error}=1,64", groups = Group2.class) + @ApiModelProperty(value = "授权类型不能为空", required = true, example = "1111", position = 2) private String grantType; diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java index 9bb753b4..b904028c 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java @@ -1,5 +1,6 @@ package com.gitee.sop.openapi.service; +import com.alibaba.fastjson.JSONObject; import com.gitee.fastmybatis.core.query.Query; import com.gitee.sop.openapi.config.RedisOperator; import com.gitee.sop.openapi.entity.IsvAuthTokenEntity; @@ -13,6 +14,7 @@ import com.gitee.sop.openapi.util.RedisKeyUtil; import com.gitee.sop.servercommon.exception.ServiceException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /*** * @@ -20,16 +22,7 @@ import org.springframework.stereotype.Service; */ @Slf4j @Service -public class AuthCodeService { - public static final int FORBIDDEN = 2; - - /** 0 插件应用未授权 **/ - public static final int UNAUTHORIZED = 0; - /** 1 插件应用已授权 **/ - public static final int AUTHORIZED = 1; - - public static final Byte ENABLE_TOKEN = 1; - public static final Byte DISABLE_TOKEN = 0; +public class AuthCodeService implements AuthService { private final IsvInfoMapper isvInfoMapper; private final IsvAuthTokenMapper isvAuthTokenMapper; @@ -43,6 +36,8 @@ public class AuthCodeService { this.redisOperator = redisOperator; } + + @Transactional public AuthCodeVo getCode(AuthCodePo authCodePo) { IsvInfoEntity isvInfo = isvInfoMapper.getByColumn("app_key", authCodePo.getAppId()); @@ -51,8 +46,6 @@ public class AuthCodeService { throw new ServiceException("应用ID未申请或已被禁用"); } - // todo check userToken and get userId - String authCode = MD5GeneratorUtil.generateValue(); Query query = new Query() @@ -65,23 +58,28 @@ public class AuthCodeService { if (authTokenEntity == null) { authCodeVo.setState(UNAUTHORIZED); authTokenEntity = new IsvAuthTokenEntity(); - authTokenEntity.setAppAuthToken(authCode); + authTokenEntity.setAppAuthCode(authCode); authTokenEntity.setAppKey(authCodePo.getAppId()); authTokenEntity.setUserId(authCodePo.getUserId()); isvAuthTokenMapper.save(authTokenEntity); } else { - authCodeVo.setState(AUTHORIZED); + authTokenEntity.setAppAuthCode(authCode); isvAuthTokenMapper.update(authTokenEntity); } // 写入redis缓存 - String codeKey = RedisKeyUtil.getCodeKey(authCodePo.getAppId(), authCodePo.getUserId()); - redisOperator.set(codeKey, authCodePo.getUserId()); + try { + String codeKey = RedisKeyUtil.getCodeKey(authCode); + redisOperator.set(codeKey, JSONObject.toJSON(authCodePo), CODE_TIMEOUT); + } catch (Exception e) { + throw new ServiceException("获取code失败"); + } return authCodeVo; } + @Transactional public void cancelToken(Long userId) { // todo check userToken and get userId @@ -94,13 +92,21 @@ public class AuthCodeService { throw new ServiceException("用户未授权插件应用"); } - authTokenEntity.setStatus(ENABLE_TOKEN); - isvAuthTokenMapper.update(authTokenEntity); + try { + authTokenEntity.setStatus(ENABLE_TOKEN); + isvAuthTokenMapper.update(authTokenEntity); + } catch (Exception e) { + throw new ServiceException("解除授权失败,系统忙,请稍后!"); + } - String tokenKey = RedisKeyUtil.getAuthTokenKey(authTokenEntity.getAppKey(), authTokenEntity.getUserId()); - String refreshKey = RedisKeyUtil.getRefreshTokenKey(authTokenEntity.getAppKey(), authTokenEntity.getUserId()); - redisOperator.del(tokenKey); - redisOperator.del(refreshKey); + String tokenKey = RedisKeyUtil.getAuthTokenKey(authTokenEntity.getAppAuthToken()); + String refreshKey = RedisKeyUtil.getRefreshTokenKey(authTokenEntity.getAppRefreshToken()); + try { + redisOperator.del(tokenKey); + redisOperator.del(refreshKey); + } catch (Exception e) { + throw new ServiceException("解除授权失败,系统忙,请稍后!"); + } } } diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthService.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthService.java new file mode 100644 index 00000000..28102e8b --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthService.java @@ -0,0 +1,20 @@ +package com.gitee.sop.openapi.service; + +/*** + * + * @author wangping created on 2020/11/4 15:41 + */ +public interface AuthService { + + int FORBIDDEN = 2; + + /** 0 插件应用未授权 **/ + int UNAUTHORIZED = 0; + /** 1 插件应用已授权 **/ + int AUTHORIZED = 1; + + Byte ENABLE_TOKEN = 1; + Byte DISABLE_TOKEN = 0; + + Long CODE_TIMEOUT = 3600L; +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthTokenService.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthTokenService.java new file mode 100644 index 00000000..ca8d13f1 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthTokenService.java @@ -0,0 +1,83 @@ +package com.gitee.sop.openapi.service; + +import com.alibaba.fastjson.JSONObject; +import com.gitee.sop.openapi.config.RedisOperator; +import com.gitee.sop.openapi.entity.IsvAuthTokenEntity; +import com.gitee.sop.openapi.mapper.IsvAuthTokenMapper; +import com.gitee.sop.openapi.po.AuthCodePo; +import com.gitee.sop.openapi.po.AuthTokePo; +import com.gitee.sop.openapi.util.GrantType; +import com.gitee.sop.openapi.util.MD5GeneratorUtil; +import com.gitee.sop.openapi.util.RedisKeyUtil; +import com.gitee.sop.openapi.vo.AuthTokenVo; +import com.gitee.sop.servercommon.exception.ServiceException; +import org.springframework.stereotype.Service; + +/*** + * + * @author wangping created on 2020/11/4 15:21 + */ +@Service +public class AuthTokenService implements AuthService { + + private final RedisOperator redisOperator; + private final IsvAuthTokenMapper isvAuthTokenMapper; + + public AuthTokenService(final RedisOperator redisOperator, + final IsvAuthTokenMapper isvAuthTokenMapper) { + this.redisOperator = redisOperator; + this.isvAuthTokenMapper = isvAuthTokenMapper; + } + + + public AuthTokenVo getToken(AuthTokePo authTokePo) { + + AuthTokenVo tokenVo = new AuthTokenVo(); + String grantType = authTokePo.getGrantType(); + if (GrantType.AUTHORIZATION_CODE.name().equals(grantType)) { + String codeKey = RedisKeyUtil.getCodeKey(authTokePo.getCode()); + Object jsonObj = redisOperator.get(codeKey); + if (jsonObj == null) { + throw new ServiceException("Invalid request"); + } + + AuthCodePo codePo = JSONObject.parseObject(jsonObj.toString(), AuthCodePo.class); + if (codePo == null) { + throw new ServiceException("Can not found user by code"); + } + IsvAuthTokenEntity authTokenEntity = isvAuthTokenMapper.getByColumn("app_auth_code", authTokePo.getCode()); + if (authTokenEntity == null) { + throw new ServiceException("Can not found user by code"); + } + + + String authToken = MD5GeneratorUtil.generateValue(); + String refreshToken = MD5GeneratorUtil.generateValue(); + + + authTokenEntity.setStatus((byte) AUTHORIZED); + authTokenEntity.setAppAuthToken(authToken); + authTokenEntity.setAppRefreshToken(refreshToken); + isvAuthTokenMapper.update(authTokenEntity); + + String authTokenKey = RedisKeyUtil.getAuthTokenKey(authToken); + String refreshTokenKey = RedisKeyUtil.getRefreshTokenKey(refreshToken); + redisOperator.set(authTokenKey, codePo); + redisOperator.set(refreshTokenKey, codePo); + + tokenVo.setAppAuthToken(authToken); + tokenVo.setAppRefreshToken(refreshToken); + tokenVo.setUserId(codePo.getUserId()); + return tokenVo; + } else if (GrantType.REFRESH_TOKEN.name().equals(grantType)) { + + + return tokenVo; + } else { + throw new ServiceException("Invalid grant"); + } + + } + + +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/util/GrantType.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/GrantType.java new file mode 100644 index 00000000..de8949ee --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/GrantType.java @@ -0,0 +1,23 @@ +package com.gitee.sop.openapi.util; + +/*** + * + * @author wangping created on 2020/11/4 15:25 + */ +public enum GrantType { + + AUTHORIZATION_CODE("authorization_code"), + PASSWORD("password"), + REFRESH_TOKEN("refresh_token"), + CLIENT_CREDENTIALS("client_credentials"); + + private String grantType; + + private GrantType(String grantType) { + this.grantType = grantType; + } + + public String toString() { + return this.grantType; + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/util/RedisKeyUtil.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/RedisKeyUtil.java index 61ec6687..19bab21c 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/util/RedisKeyUtil.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/util/RedisKeyUtil.java @@ -16,15 +16,15 @@ public class RedisKeyUtil { private static final Joiner JOINER = Joiner.on(":"); - public static String getCodeKey(String appId, Long userId) { - return JOINER.join(CODE_PREFIX, appId, userId); + public static String getCodeKey(String code) { + return JOINER.join(CODE_PREFIX, code); } - public static String getAuthTokenKey(String appId, Long userId) { - return JOINER.join(AUTH_TOKEN_PREFIX, appId, userId); + public static String getAuthTokenKey(String token) { + return JOINER.join(AUTH_TOKEN_PREFIX, token); } - public static String getRefreshTokenKey(String appId, Long userId) { - return JOINER.join(REFRESH_TOKEN_PREFIX, appId, userId); + public static String getRefreshTokenKey(String refreshToken) { + return JOINER.join(REFRESH_TOKEN_PREFIX, refreshToken); } } diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/vo/AuthTokenVo.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/vo/AuthTokenVo.java new file mode 100644 index 00000000..c8476430 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/vo/AuthTokenVo.java @@ -0,0 +1,40 @@ +package com.gitee.sop.openapi.vo; + +import lombok.Data; + +/*** + * + * @author wangping created on 2020/11/4 15:22 + */ +@Data +public class AuthTokenVo { + + /** + * 授权令牌 + */ + private String appAuthToken; + + /** + * 用户id + */ + private Long userId; + + + /** + * 令牌有效期. -1:永久有效 + */ + private long expiresIn = -1; + + /** + * 刷新令牌有效期. -1:永久有效 + */ + private long reExpiresIn = -1; + + + /** + * 刷新令牌时使用。 + * 刷新令牌后,我们会保证老的app_auth_token从刷新开始10分钟内可继续使用,请及时替换为最新token + */ + private String appRefreshToken; + +} diff --git a/sop-openapi/src/main/resources/application-standalone.yml b/sop-openapi/src/main/resources/application-standalone.yml index 12b1ea14..89510048 100644 --- a/sop-openapi/src/main/resources/application-standalone.yml +++ b/sop-openapi/src/main/resources/application-standalone.yml @@ -1,6 +1,6 @@ spring: redis: - host: 10.0.0.39 + host: localhost port: 6379 jedis: pool: @@ -10,4 +10,4 @@ spring: min-idle: 1 database: 0 timeout: 60000 - password: lt@3600 + password: diff --git a/sop-openapi/src/main/resources/application.properties b/sop-openapi/src/main/resources/application.properties index 91aad173..b208c10a 100644 --- a/sop-openapi/src/main/resources/application.properties +++ b/sop-openapi/src/main/resources/application.properties @@ -1,6 +1,6 @@ spring.profiles.active=dev server.port=8089 -spring.application.name=sop-openapi +spring.application.name=open-apis # ע spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 \ No newline at end of file From e155866ad172c07b8fbd95a8412d4d6dc70c897f Mon Sep 17 00:00:00 2001 From: wangping Date: Wed, 4 Nov 2020 19:22:14 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8jpa=E4=BD=9C?= =?UTF-8?q?=E4=B8=BAorm=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-openapi/pom.xml | 9 ++- .../gitee/sop/openapi/entity/BaseEntity.java | 61 +++++++++++++++++++ .../openapi/entity/IsvAuthTokenEntity.java | 21 +++---- .../sop/openapi/entity/IsvInfoEntity.java | 23 ++++--- .../openapi/mapper/IsvAuthTokenMapper.java | 11 ---- .../sop/openapi/mapper/IsvInfoMapper.java | 11 ---- .../repository/IsvAuthTokenRepository.java | 17 ++++++ .../openapi/repository/IsvInfoRepository.java | 14 +++++ .../sop/openapi/service/AuthCodeService.java | 36 +++++------ .../sop/openapi/service/AuthTokenService.java | 14 ++--- .../src/main/resources/application.properties | 26 +++++++- 11 files changed, 168 insertions(+), 75 deletions(-) create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/entity/BaseEntity.java delete mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvAuthTokenMapper.java delete mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvInfoMapper.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/repository/IsvAuthTokenRepository.java create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/repository/IsvInfoRepository.java diff --git a/sop-openapi/pom.xml b/sop-openapi/pom.xml index f035b864..39158e49 100644 --- a/sop-openapi/pom.xml +++ b/sop-openapi/pom.xml @@ -6,7 +6,7 @@ com.gitee.sop sop-parent - 4.0.3-SNAPSHOT + 4.1.0-SNAPSHOT ../pom.xml com.gitee.sop.openapi @@ -17,7 +17,7 @@ com.gitee.sop sop-service-common - 4.0.3-SNAPSHOT + 4.1.0-SNAPSHOT @@ -87,6 +87,11 @@ 1.18.4 provided + + + org.springframework.boot + spring-boot-starter-data-jpa + diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/BaseEntity.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/BaseEntity.java new file mode 100644 index 00000000..86d61b0d --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/BaseEntity.java @@ -0,0 +1,61 @@ +package com.gitee.sop.openapi.entity; + +import com.google.common.base.MoreObjects; +import lombok.Data; + +import javax.persistence.*; +import java.util.Date; + +/*** + * + * @author wangping created on 2020/11/4 18:59 + */ +@Data +@MappedSuperclass +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +public abstract class BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "gmt_create", nullable = false) + private Date gmtCreate; + + @Column(name = "gmt_modified") + private Date gmtModified; + + @PrePersist + protected void prePersist() { + if (this.gmtCreate == null) { + gmtCreate = new Date(); + } + if (this.gmtModified == null) { + gmtModified = new Date(); + } + } + + @PreUpdate + protected void preUpdate() { + this.gmtModified = new Date(); + } + + @PreRemove + protected void preRemove() { + this.gmtModified = new Date(); + } + + protected MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this) + .omitNullValues() + .add("id", id) + .add("gmtCreate", gmtCreate) + .add("gmtModified", gmtModified); + } + + @Override + public String toString() { + return toStringHelper().toString(); + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java index 2fae85fa..2058f25b 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvAuthTokenEntity.java @@ -1,11 +1,9 @@ package com.gitee.sop.openapi.entity; import lombok.Data; -import org.springframework.data.annotation.Id; import javax.persistence.Column; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; +import javax.persistence.Entity; import javax.persistence.Table; /*** @@ -14,30 +12,31 @@ import javax.persistence.Table; */ @Data +@Entity @Table(name = "isv_auth_token") -public class IsvAuthTokenEntity { - - @Id - @Column(name = "id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - /** 数据库字段:id */ - private Long id; +public class IsvAuthTokenEntity extends BaseEntity { /** appKey, 数据库字段:app_key */ + @Column(name = "app_key") private String appKey; /** userId, 数据库字段:user_id */ + @Column(name = "user_id") private Long userId; /** 1启用,2禁用, 数据库字段:status */ - private Byte status; + @Column(name = "status", columnDefinition = "Bit default '1'") + private Boolean status = true; /** appAuthCode 数据库字段:app_auth_code */ + @Column(name = "app_auth_code") private String appAuthCode; /** appAuthToken 数据库字段:app_auth_token */ + @Column(name = "app_auth_token") private String appAuthToken; /** appRefreshToken 数据库字段:app_refresh_token */ + @Column(name = "app_refresh_token") private String appRefreshToken; } diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvInfoEntity.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvInfoEntity.java index a20d384a..81eb2761 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvInfoEntity.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/entity/IsvInfoEntity.java @@ -1,11 +1,9 @@ package com.gitee.sop.openapi.entity; import lombok.Data; -import org.springframework.data.annotation.Id; import javax.persistence.Column; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; +import javax.persistence.Entity; import javax.persistence.Table; /*** @@ -13,18 +11,23 @@ import javax.persistence.Table; * @author wangping created on 2020/11/2 16:22 */ @Data +@Entity @Table(name = "isv_info") -public class IsvInfoEntity { - - @Id - @Column(name = "id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - /** 数据库字段:id */ - private Long id; +public class IsvInfoEntity extends BaseEntity { /** appKey, 数据库字段:app_key */ + @Column(name = "app_key") private String appKey; /** 1启用,2禁用, 数据库字段:status */ + @Column(name = "status") private Byte status; + + /** 1:RSA2,2:MD5 */ + @Column(name = "sign_type") + private Byte signType; + + @Column(name = "remark") + private String remark; + } diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvAuthTokenMapper.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvAuthTokenMapper.java deleted file mode 100644 index eda698cf..00000000 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvAuthTokenMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gitee.sop.openapi.mapper; - -import com.gitee.fastmybatis.core.mapper.CrudMapper; -import com.gitee.sop.openapi.entity.IsvAuthTokenEntity; - -/*** - * - * @author wangping created on 2020/11/2 16:59 - */ -public interface IsvAuthTokenMapper extends CrudMapper { -} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvInfoMapper.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvInfoMapper.java deleted file mode 100644 index 46bc108d..00000000 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/mapper/IsvInfoMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gitee.sop.openapi.mapper; - -import com.gitee.fastmybatis.core.mapper.CrudMapper; -import com.gitee.sop.openapi.entity.IsvInfoEntity; - -/*** - * - * @author wangping created on 2020/11/2 15:52 - */ -public interface IsvInfoMapper extends CrudMapper { -} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/repository/IsvAuthTokenRepository.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/repository/IsvAuthTokenRepository.java new file mode 100644 index 00000000..534b806f --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/repository/IsvAuthTokenRepository.java @@ -0,0 +1,17 @@ +package com.gitee.sop.openapi.repository; + +import com.gitee.sop.openapi.entity.IsvAuthTokenEntity; +import org.springframework.data.repository.PagingAndSortingRepository; + +/*** + * + * @author wangping created on 2020/11/4 19:12 + */ +public interface IsvAuthTokenRepository extends PagingAndSortingRepository { + + IsvAuthTokenEntity findFirstByAppKeyAndUserIdAndStatusTrue(String appKey, Long userId); + + IsvAuthTokenEntity findFirstByUserIdAndStatusTrue(Long userId); + + IsvAuthTokenEntity findFirstByAppAuthCode(String appAuthCode); +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/repository/IsvInfoRepository.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/repository/IsvInfoRepository.java new file mode 100644 index 00000000..218915b2 --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/repository/IsvInfoRepository.java @@ -0,0 +1,14 @@ +package com.gitee.sop.openapi.repository; + +import com.gitee.sop.openapi.entity.IsvInfoEntity; +import org.springframework.data.repository.PagingAndSortingRepository; + +/*** + * + * @author wangping created on 2020/11/4 19:11 + */ +public interface IsvInfoRepository extends PagingAndSortingRepository { + + IsvInfoEntity findFirstByAppKey(String appKey); + +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java index b904028c..1daa402e 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthCodeService.java @@ -5,9 +5,9 @@ import com.gitee.fastmybatis.core.query.Query; import com.gitee.sop.openapi.config.RedisOperator; import com.gitee.sop.openapi.entity.IsvAuthTokenEntity; import com.gitee.sop.openapi.entity.IsvInfoEntity; -import com.gitee.sop.openapi.mapper.IsvAuthTokenMapper; -import com.gitee.sop.openapi.mapper.IsvInfoMapper; import com.gitee.sop.openapi.po.AuthCodePo; +import com.gitee.sop.openapi.repository.IsvAuthTokenRepository; +import com.gitee.sop.openapi.repository.IsvInfoRepository; import com.gitee.sop.openapi.vo.AuthCodeVo; import com.gitee.sop.openapi.util.MD5GeneratorUtil; import com.gitee.sop.openapi.util.RedisKeyUtil; @@ -24,15 +24,15 @@ import org.springframework.transaction.annotation.Transactional; @Service public class AuthCodeService implements AuthService { - private final IsvInfoMapper isvInfoMapper; - private final IsvAuthTokenMapper isvAuthTokenMapper; + private final IsvInfoRepository isvInfoRepository; + private final IsvAuthTokenRepository isvAuthTokenRepository; private final RedisOperator redisOperator; - public AuthCodeService(final IsvInfoMapper isvInfoMapper, - final IsvAuthTokenMapper isvAuthTokenMapper, + public AuthCodeService(final IsvInfoRepository isvInfoRepository, + final IsvAuthTokenRepository isvAuthTokenRepository, final RedisOperator redisOperator) { - this.isvInfoMapper = isvInfoMapper; - this.isvAuthTokenMapper = isvAuthTokenMapper; + this.isvInfoRepository = isvInfoRepository; + this.isvAuthTokenRepository = isvAuthTokenRepository; this.redisOperator = redisOperator; } @@ -40,7 +40,7 @@ public class AuthCodeService implements AuthService { @Transactional public AuthCodeVo getCode(AuthCodePo authCodePo) { - IsvInfoEntity isvInfo = isvInfoMapper.getByColumn("app_key", authCodePo.getAppId()); + IsvInfoEntity isvInfo = isvInfoRepository.findFirstByAppKey(authCodePo.getAppId()); if (isvInfo == null || isvInfo.getStatus().intValue() == FORBIDDEN) { log.error("appId已禁用:{}", authCodePo.getAppId()); throw new ServiceException("应用ID未申请或已被禁用"); @@ -48,11 +48,7 @@ public class AuthCodeService implements AuthService { String authCode = MD5GeneratorUtil.generateValue(); - Query query = new Query() - .eq("app_key", authCodePo.getAppId()) - .eq("user_id", authCodePo.getUserId()) - .eq("status", ENABLE_TOKEN); - IsvAuthTokenEntity authTokenEntity = isvAuthTokenMapper.getByQuery(query); + IsvAuthTokenEntity authTokenEntity = isvAuthTokenRepository.findFirstByAppKeyAndUserIdAndStatusTrue(authCodePo.getAppId(), authCodePo.getUserId()); AuthCodeVo authCodeVo = new AuthCodeVo(); authCodeVo.setCode(authCode); if (authTokenEntity == null) { @@ -61,11 +57,9 @@ public class AuthCodeService implements AuthService { authTokenEntity.setAppAuthCode(authCode); authTokenEntity.setAppKey(authCodePo.getAppId()); authTokenEntity.setUserId(authCodePo.getUserId()); - isvAuthTokenMapper.save(authTokenEntity); - } else { - authTokenEntity.setAppAuthCode(authCode); - isvAuthTokenMapper.update(authTokenEntity); } + authTokenEntity.setAppAuthCode(authCode); + isvAuthTokenRepository.save(authTokenEntity); // 写入redis缓存 try { @@ -87,14 +81,14 @@ public class AuthCodeService implements AuthService { .eq("user_id", userId) .eq("status", ENABLE_TOKEN); - IsvAuthTokenEntity authTokenEntity = isvAuthTokenMapper.getByQuery(query); + IsvAuthTokenEntity authTokenEntity = isvAuthTokenRepository.findFirstByUserIdAndStatusTrue(userId); if (authTokenEntity == null) { throw new ServiceException("用户未授权插件应用"); } try { - authTokenEntity.setStatus(ENABLE_TOKEN); - isvAuthTokenMapper.update(authTokenEntity); + authTokenEntity.setStatus(true); + isvAuthTokenRepository.save(authTokenEntity); } catch (Exception e) { throw new ServiceException("解除授权失败,系统忙,请稍后!"); } diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthTokenService.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthTokenService.java index ca8d13f1..f3a2c514 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthTokenService.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/service/AuthTokenService.java @@ -3,9 +3,9 @@ package com.gitee.sop.openapi.service; import com.alibaba.fastjson.JSONObject; import com.gitee.sop.openapi.config.RedisOperator; import com.gitee.sop.openapi.entity.IsvAuthTokenEntity; -import com.gitee.sop.openapi.mapper.IsvAuthTokenMapper; import com.gitee.sop.openapi.po.AuthCodePo; import com.gitee.sop.openapi.po.AuthTokePo; +import com.gitee.sop.openapi.repository.IsvAuthTokenRepository; import com.gitee.sop.openapi.util.GrantType; import com.gitee.sop.openapi.util.MD5GeneratorUtil; import com.gitee.sop.openapi.util.RedisKeyUtil; @@ -21,12 +21,12 @@ import org.springframework.stereotype.Service; public class AuthTokenService implements AuthService { private final RedisOperator redisOperator; - private final IsvAuthTokenMapper isvAuthTokenMapper; + private final IsvAuthTokenRepository isvAuthTokenRepository; public AuthTokenService(final RedisOperator redisOperator, - final IsvAuthTokenMapper isvAuthTokenMapper) { + final IsvAuthTokenRepository isvAuthTokenRepository) { this.redisOperator = redisOperator; - this.isvAuthTokenMapper = isvAuthTokenMapper; + this.isvAuthTokenRepository = isvAuthTokenRepository; } @@ -45,7 +45,7 @@ public class AuthTokenService implements AuthService { if (codePo == null) { throw new ServiceException("Can not found user by code"); } - IsvAuthTokenEntity authTokenEntity = isvAuthTokenMapper.getByColumn("app_auth_code", authTokePo.getCode()); + IsvAuthTokenEntity authTokenEntity = isvAuthTokenRepository.findFirstByAppAuthCode(authTokePo.getCode()); if (authTokenEntity == null) { throw new ServiceException("Can not found user by code"); } @@ -55,10 +55,10 @@ public class AuthTokenService implements AuthService { String refreshToken = MD5GeneratorUtil.generateValue(); - authTokenEntity.setStatus((byte) AUTHORIZED); + authTokenEntity.setStatus(true); authTokenEntity.setAppAuthToken(authToken); authTokenEntity.setAppRefreshToken(refreshToken); - isvAuthTokenMapper.update(authTokenEntity); + isvAuthTokenRepository.save(authTokenEntity); String authTokenKey = RedisKeyUtil.getAuthTokenKey(authToken); String refreshTokenKey = RedisKeyUtil.getRefreshTokenKey(refreshToken); diff --git a/sop-openapi/src/main/resources/application.properties b/sop-openapi/src/main/resources/application.properties index b208c10a..3ce313c5 100644 --- a/sop-openapi/src/main/resources/application.properties +++ b/sop-openapi/src/main/resources/application.properties @@ -1,6 +1,28 @@ -spring.profiles.active=dev +spring.profiles.active=standalone server.port=8089 spring.application.name=open-apis # ע -spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 \ No newline at end of file +spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 + + +## ݿ +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.datasource.url=jdbc:mysql://localhost:3306/sop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai +spring.datasource.username=root +spring.datasource.password=root +spring.datasource.hikari.connectionInitSql=set names utf8mb4 + +#ӳ +spring.datasource.hikari.pool-name=HikariCP +spring.datasource.hikari.max-lifetime=500000 +spring.datasource.hikari.minimum-idle=2 +spring.datasource.hikari.idle-timeout=60000 +spring.datasource.hikari.maximum-pool-size=10 +spring.datasource.hikari.connection-test-query=select 1 + +# Naming strategy +spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl +spring.jpa.hibernate.globally_quoted_identifiers=true +spring.jpa.properties.hibernate.globally_quoted_identifiers=true +spring.jpa.show-sql=false \ No newline at end of file From 2d3144a9bc40d7f71ea276d477d7cd5351fa2b3a Mon Sep 17 00:00:00 2001 From: wangping Date: Thu, 5 Nov 2020 16:23:26 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=E5=BC=95=E5=85=A5Apollo=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-openapi/pom.xml | 10 +++++ .../config/ApolloApplicationConfig.java | 41 +++++++++++++++++++ .../controller/AuthCodeController.java | 31 +++++++++++++- .../main/resources/META-INF/app.properties | 2 + .../main/resources/application-standalone.yml | 6 +-- .../src/main/resources/application.properties | 11 ++++- 6 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 sop-openapi/src/main/java/com/gitee/sop/openapi/config/ApolloApplicationConfig.java create mode 100644 sop-openapi/src/main/resources/META-INF/app.properties diff --git a/sop-openapi/pom.xml b/sop-openapi/pom.xml index 39158e49..c231dc6c 100644 --- a/sop-openapi/pom.xml +++ b/sop-openapi/pom.xml @@ -13,6 +13,10 @@ sop-openapi sop-openapi + + 1.1.0 + + com.gitee.sop @@ -92,6 +96,12 @@ org.springframework.boot spring-boot-starter-data-jpa + + + com.ctrip.framework.apollo + apollo-client + ${apollo.version} + diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/config/ApolloApplicationConfig.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/config/ApolloApplicationConfig.java new file mode 100644 index 00000000..4b3adc8c --- /dev/null +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/config/ApolloApplicationConfig.java @@ -0,0 +1,41 @@ +package com.gitee.sop.openapi.config; + +import com.ctrip.framework.apollo.Config; +import com.ctrip.framework.apollo.ConfigService; +import com.ctrip.framework.apollo.model.ConfigChange; +import com.ctrip.framework.apollo.model.ConfigChangeEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/*** + * + * @author wangping created on 2020/11/5 16:06 + */ +@Slf4j +@Component +public class ApolloApplicationConfig implements BeanPostProcessor { + + + @PostConstruct + public void init() { + loadApplication(); + } + + private void loadApplication() { + Config config = ConfigService.getAppConfig(); + config.addChangeListener(this::getChangedEvent); + } + + + private void getChangedEvent(ConfigChangeEvent changeEvent) { + for (String key : changeEvent.changedKeys()) { + ConfigChange change = changeEvent.getChange(key); + log.info("Found change - key: {}, oldValue: {}, newValue: {}, changeType:{}", + change.getPropertyName(), change.getOldValue(), + change.getNewValue(), change.getChangeType()); + } + } +} diff --git a/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthCodeController.java b/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthCodeController.java index 3e7b3c55..323ba832 100644 --- a/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthCodeController.java +++ b/sop-openapi/src/main/java/com/gitee/sop/openapi/controller/AuthCodeController.java @@ -1,14 +1,18 @@ package com.gitee.sop.openapi.controller; +import com.gitee.sop.openapi.config.RedisOperator; import com.gitee.sop.openapi.po.AuthCodePo; import com.gitee.sop.openapi.vo.AuthCodeVo; import com.gitee.sop.openapi.service.AuthCodeService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.NotBlank; +import java.util.HashMap; +import java.util.Map; @Slf4j @RestController @@ -17,9 +21,23 @@ public class AuthCodeController { private final AuthCodeService authCodeService; + private final RedisOperator redisOperator; - public AuthCodeController(final AuthCodeService authCodeService) { + + @Value("${test.redis}") + private String testRedis; + + public void setTestRedis(String testRedis) { + this.testRedis = testRedis; + } + + public String getTestRedis() { + return testRedis; + } + + public AuthCodeController(final AuthCodeService authCodeService, final RedisOperator redisOperator) { this.authCodeService = authCodeService; + this.redisOperator = redisOperator; } @@ -36,4 +54,15 @@ public class AuthCodeController { authCodeService.cancelToken(userId); } + + @ApiOperation(value = "测试接口") + @GetMapping("/test") + public Map test() { + Map map = new HashMap<>(); + map.put("code", 0); + map.put("msg", "success"); + redisOperator.set("test11", testRedis); + return map; + } + } diff --git a/sop-openapi/src/main/resources/META-INF/app.properties b/sop-openapi/src/main/resources/META-INF/app.properties new file mode 100644 index 00000000..596945c0 --- /dev/null +++ b/sop-openapi/src/main/resources/META-INF/app.properties @@ -0,0 +1,2 @@ +app.id=open-apis +jdkVersion=1.8 diff --git a/sop-openapi/src/main/resources/application-standalone.yml b/sop-openapi/src/main/resources/application-standalone.yml index 89510048..4e4735a5 100644 --- a/sop-openapi/src/main/resources/application-standalone.yml +++ b/sop-openapi/src/main/resources/application-standalone.yml @@ -1,7 +1,7 @@ spring: redis: - host: localhost - port: 6379 + host: 52.81.162.154 + port: 8095 jedis: pool: max-active: 10 @@ -10,4 +10,4 @@ spring: min-idle: 1 database: 0 timeout: 60000 - password: + password: zixun@2020! diff --git a/sop-openapi/src/main/resources/application.properties b/sop-openapi/src/main/resources/application.properties index 3ce313c5..b0b24634 100644 --- a/sop-openapi/src/main/resources/application.properties +++ b/sop-openapi/src/main/resources/application.properties @@ -25,4 +25,13 @@ spring.datasource.hikari.connection-test-query=select 1 spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl spring.jpa.hibernate.globally_quoted_identifiers=true spring.jpa.properties.hibernate.globally_quoted_identifiers=true -spring.jpa.show-sql=false \ No newline at end of file +spring.jpa.show-sql=false + + +# Apollo +app.id=open-apis +apollo.bootstrap.enabled=true +apollo.bootstrap.namespaces=application +apollo.bootstrap.eagerLoad.enable=true + +test.redis=wangping \ No newline at end of file