- 后端:更新 README

- 后端:重构部分代码
This commit is contained in:
YunaiV
2019-05-17 19:23:26 +08:00
parent 68027b9f16
commit dbf2a43924
108 changed files with 589 additions and 1017 deletions

View File

@@ -1,29 +0,0 @@
package cn.iocoder.mall.user.biz.convert;
import cn.iocoder.mall.user.biz.dataobject.OAuth2AccessTokenDO;
import cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO;
import cn.iocoder.mall.user.api.bo.OAuth2AuthenticationBO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface OAuth2Convert {
OAuth2Convert INSTANCE = Mappers.getMapper(OAuth2Convert.class);
@Mappings({
@Mapping(source = "id", target = "accessToken")
})
OAuth2AccessTokenBO convertToAccessToken(OAuth2AccessTokenDO oauth2AccessTokenDO);
default OAuth2AccessTokenBO convertToAccessTokenWithExpiresIn(OAuth2AccessTokenDO oauth2AccessTokenDO) {
return this.convertToAccessToken(oauth2AccessTokenDO)
.setExpiresIn(Math.max((int) ((oauth2AccessTokenDO.getExpiresTime().getTime() - System.currentTimeMillis()) / 1000), 0));
}
@Mappings({})
OAuth2AuthenticationBO convertToAuthentication(OAuth2AccessTokenDO oauth2AccessTokenDO);
}

View File

@@ -1,17 +0,0 @@
package cn.iocoder.mall.user.biz.convert;
import cn.iocoder.mall.user.biz.dataobject.UserAccessLogDO;
import cn.iocoder.mall.user.api.dto.UserAccessLogAddDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UserAccessLogConvert {
UserAccessLogConvert INSTANCE = Mappers.getMapper(UserAccessLogConvert.class);
@Mappings({})
UserAccessLogDO convert(UserAccessLogAddDTO adminAccessLogAddDTO);
}

View File

@@ -1,18 +0,0 @@
package cn.iocoder.mall.user.biz.dao;
import cn.iocoder.mall.user.biz.dataobject.OAuth2AccessTokenDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface OAuth2AccessTokenMapper {
void insert(OAuth2AccessTokenDO entity);
OAuth2AccessTokenDO selectByTokenId(String tokenId);
void updateToInvalidByUserId(@Param("userId") Integer userId);
void updateToInvalidByRefreshToken(@Param("refreshToken") String refreshToken);
}

View File

@@ -1,16 +0,0 @@
package cn.iocoder.mall.user.biz.dao;
import cn.iocoder.mall.user.biz.dataobject.OAuth2RefreshTokenDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface OAuth2RefreshTokenMapper {
void insert(OAuth2RefreshTokenDO entity);
void updateToInvalidByUserId(@Param("userId") Integer userId);
OAuth2RefreshTokenDO selectById(@Param("id") String id);
}

View File

@@ -1,11 +0,0 @@
package cn.iocoder.mall.user.biz.dao;
import cn.iocoder.mall.user.biz.dataobject.UserAccessLogDO;
import org.springframework.stereotype.Repository;
@Repository
public interface UserAccessLogMapper {
void insert(UserAccessLogDO entity);
}

View File

@@ -1,129 +0,0 @@
package cn.iocoder.mall.user.biz.service;
import cn.iocoder.common.framework.exception.ServiceException;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.user.api.OAuth2Service;
import cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO;
import cn.iocoder.mall.user.api.bo.OAuth2AuthenticationBO;
import cn.iocoder.mall.user.api.constant.UserErrorCodeEnum;
import cn.iocoder.mall.user.biz.convert.OAuth2Convert;
import cn.iocoder.mall.user.biz.dao.OAuth2AccessTokenMapper;
import cn.iocoder.mall.user.biz.dao.OAuth2RefreshTokenMapper;
import cn.iocoder.mall.user.biz.dataobject.MobileCodeDO;
import cn.iocoder.mall.user.biz.dataobject.OAuth2AccessTokenDO;
import cn.iocoder.mall.user.biz.dataobject.OAuth2RefreshTokenDO;
import cn.iocoder.mall.user.biz.dataobject.UserDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.util.Date;
import java.util.UUID;
/**
* OAuth2Service ,实现用户授权相关的逻辑
*/
@Service
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.OAuth2Service.version}")
public class OAuth2ServiceImpl implements OAuth2Service {
/**
* 访问令牌过期时间,单位:毫秒
*/
@Value("${modules.oauth2-code-service.access-token-expire-time-millis}")
private int accessTokenExpireTimeMillis;
/**
* 刷新令牌过期时间,单位:毫秒
*/
@Value("${modules.oauth2-code-service.refresh-token-expire-time-millis}")
private int refreshTokenExpireTimeMillis;
@Autowired
private UserServiceImpl userService;
@Autowired
private MobileCodeServiceImpl mobileCodeService;
@Autowired
private OAuth2AccessTokenMapper oauth2AccessTokenMapper;
@Autowired
private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
@Override
public OAuth2AuthenticationBO checkToken(String accessToken) throws ServiceException {
OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByTokenId(accessToken);
if (accessTokenDO == null) { // 不存在
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.OAUTH_INVALID_ACCESS_TOKEN_NOT_FOUND.getCode());
}
if (accessTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.OAUTH_INVALID_ACCESS_TOKEN_EXPIRED.getCode());
}
if (!accessTokenDO.getValid()) { // 无效
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.OAUTH_INVALID_ACCESS_TOKEN_INVALID.getCode());
}
// 转换返回
return OAuth2Convert.INSTANCE.convertToAuthentication(accessTokenDO);
}
@Override
public OAuth2AccessTokenBO refreshToken(String refreshToken) {
OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectById(refreshToken);
// 校验刷新令牌是否合法
if (refreshTokenDO == null) { // 不存在
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND.getCode());
}
if (refreshTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.OAUTH_INVALID_REFRESH_TOKEN_EXPIRED.getCode());
}
if (!refreshTokenDO.getValid()) { // 无效
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.OAUTH_INVALID_REFRESH_TOKEN_INVALID.getCode());
}
// 标记 refreshToken 对应的 accessToken 都不合法
oauth2AccessTokenMapper.updateToInvalidByRefreshToken(refreshToken);
// 创建访问令牌
OAuth2AccessTokenDO oauth2AccessTokenDO = createOAuth2AccessToken(refreshTokenDO.getUserId(), refreshTokenDO.getId());
// 转换返回
return OAuth2Convert.INSTANCE.convertToAccessTokenWithExpiresIn(oauth2AccessTokenDO);
}
/**
* 移除用户对应的 Token
*
* @param userId 管理员编号
*/
@Transactional
public void removeToken(Integer userId) {
// 设置 access token 失效
oauth2AccessTokenMapper.updateToInvalidByUserId(userId);
// 设置 refresh token 失效
oauth2RefreshTokenMapper.updateToInvalidByUserId(userId);
}
private OAuth2AccessTokenDO createOAuth2AccessToken(Integer uid, String refreshToken) {
OAuth2AccessTokenDO accessToken = new OAuth2AccessTokenDO().setId(generateAccessToken())
.setRefreshToken(refreshToken)
.setUserId(uid)
.setExpiresTime(new Date(System.currentTimeMillis() + accessTokenExpireTimeMillis))
.setValid(true);
oauth2AccessTokenMapper.insert(accessToken);
return accessToken;
}
private OAuth2RefreshTokenDO createOAuth2RefreshToken(Integer uid) {
OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO().setId(generateRefreshToken())
.setUserId(uid)
.setExpiresTime(new Date(System.currentTimeMillis() + refreshTokenExpireTimeMillis))
.setValid(true);
oauth2RefreshTokenMapper.insert(refreshToken);
return refreshToken;
}
private String generateAccessToken() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
private String generateRefreshToken() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
}

View File

@@ -1,54 +0,0 @@
package cn.iocoder.mall.user.biz.service;
import cn.iocoder.common.framework.util.StringUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.biz.dao.UserAccessLogMapper;
import cn.iocoder.mall.user.biz.dataobject.UserAccessLogDO;
import cn.iocoder.mall.user.api.UserAccessLogService;
import cn.iocoder.mall.user.api.dto.UserAccessLogAddDTO;
import cn.iocoder.mall.user.biz.convert.UserAccessLogConvert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.UserAccessLogService.version}")
public class UserAccessLogServiceImpl implements UserAccessLogService {
/**
* 请求参数最大长度。
*/
private static final Integer QUERY_STRING_MAX_LENGTH = 4096;
/**
* 请求地址最大长度。
*/
private static final Integer URI_MAX_LENGTH = 4096;
/**
* User-Agent 最大长度。
*/
private static final Integer USER_AGENT_MAX_LENGTH = 1024;
@Autowired
private UserAccessLogMapper userAccessLogMapper;
@Override
public void addUserAccessLog(UserAccessLogAddDTO userAccessLogAddDTO) {
// 创建 UserAccessLogDO
UserAccessLogDO accessLog = UserAccessLogConvert.INSTANCE.convert(userAccessLogAddDTO);
accessLog.setCreateTime(new Date());
// 截取最大长度
if (accessLog.getUri().length() > URI_MAX_LENGTH) {
accessLog.setUri(StringUtil.substring(accessLog.getUri(), URI_MAX_LENGTH));
}
if (accessLog.getQueryString().length() > QUERY_STRING_MAX_LENGTH) {
accessLog.setQueryString(StringUtil.substring(accessLog.getQueryString(), QUERY_STRING_MAX_LENGTH));
}
if (accessLog.getUserAgent().length() > USER_AGENT_MAX_LENGTH) {
accessLog.setUserAgent(StringUtil.substring(accessLog.getUserAgent(), USER_AGENT_MAX_LENGTH));
}
// 插入
userAccessLogMapper.insert(accessLog);
}
}

View File

@@ -9,6 +9,7 @@ import cn.iocoder.common.framework.util.ValidationUtil;
import cn.iocoder.mall.admin.api.OAuth2Service;
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AccessTokenBO;
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2CreateTokenDTO;
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2RemoveTokenByUserDTO;
import cn.iocoder.mall.user.api.UserService;
import cn.iocoder.mall.user.api.bo.user.UserAuthenticationBO;
import cn.iocoder.mall.user.api.bo.UserBO;
@@ -155,7 +156,7 @@ public class UserServiceImpl implements UserService {
userMapper.update(updateUser);
// 如果是关闭管理员,则标记 token 失效。否则,管理员还可以继续蹦跶
if (CommonStatusEnum.DISABLE.getValue().equals(status)) {
oAuth2Service.removeToken(userId);
oAuth2Service.removeToken(new OAuth2RemoveTokenByUserDTO().setUserId(userId).setUserType(UserTypeEnum.USER.getValue()));
}
// 返回成功
return true;

View File

@@ -3,6 +3,3 @@
modules.mobile-code-service.code-expire-time-millis = 600000
modules.mobile-code-service.send-maximum-quantity-per-day = 10
modules.mobile-code-service.send-frequency = 60000
## OAuth2CodeService
modules.oauth2-code-service.access-token-expire-time-millis = 2880000
modules.oauth2-code-service.refresh-token-expire-time-millis = 43200000

View File

@@ -33,8 +33,6 @@ dubbo:
filter: -exception
MobileCodeService:
version: 1.0.0
OAuth2Service:
version: 1.0.0
UserAccessLogService:
version: 1.0.0
UserAddressService:

View File

@@ -1,36 +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="cn.iocoder.mall.user.biz.dao.OAuth2AccessTokenMapper">
<insert id="insert" parameterType="OAuth2AccessTokenDO">
INSERT INTO oauth2_access_token (
id, refresh_token, user_id, valid, expires_time,
create_time
) VALUES (
#{id}, #{refreshToken}, #{userId}, #{valid}, #{expiresTime},
#{createTime}
)
</insert>
<select id="selectByTokenId" parameterType="String" resultType="OAuth2AccessTokenDO">
SELECT
id, user_id, valid, expires_time
FROM oauth2_access_token
WHERE id = #{id}
</select>
<update id="updateToInvalidByUserId" parameterType="Integer">
UPDATE oauth2_access_token
SET valid = 0
WHERE user_id = #{userId}
AND valid = 1
</update>
<update id="updateToInvalidByRefreshToken" parameterType="String">
UPDATE oauth2_access_token
SET valid = 0
WHERE refresh_token = #{refreshToken}
AND valid = 1
</update>
</mapper>

View File

@@ -1,27 +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="cn.iocoder.mall.user.biz.dao.OAuth2RefreshTokenMapper">
<insert id="insert" parameterType="OAuth2RefreshTokenDO">
INSERT INTO oauth2_refresh_token (
id, user_id, valid, expires_time, create_time
) VALUES (
#{id}, #{userId}, #{valid}, #{expiresTime}, #{createTime}
)
</insert>
<update id="updateToInvalidByUserId" parameterType="Integer">
UPDATE oauth2_refresh_token
SET valid = 0
WHERE user_id = #{userId}
AND valid = 1
</update>
<select id="selectById" parameterType="string" resultType="cn.iocoder.mall.user.biz.dataobject.OAuth2RefreshTokenDO">
SELECT
id, user_id, valid, expires_time, create_time
FROM oauth2_refresh_token
WHERE id = #{id}
</select>
</mapper>

View File

@@ -1,20 +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="cn.iocoder.mall.user.biz.dao.UserAccessLogMapper">
<!--<sql id="FIELDS">-->
<!--id, username, nickname, password, status,-->
<!--create_time-->
<!--</sql>-->
<insert id="insert" parameterType="UserAccessLogDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO user_access_log (
user_id, uri, query_string, method, user_agent,
ip, start_time, response_time, create_time
) VALUES (
#{userId}, #{uri}, #{queryString}, #{method}, #{userAgent},
#{ip}, #{startTime}, #{responseTime}, #{createTime}
)
</insert>
</mapper>