前端:整理首页
前端:修复订单列表和详情价格展示错误 前端:H5 页面的登陆拦截补充 后端 + 前端:增加 refreshToken 刷新 accessToken
This commit is contained in:
@@ -2,12 +2,13 @@ package cn.iocoder.mall.user.application.controller.users;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.user.application.convert.PassportConvert;
|
||||
import cn.iocoder.mall.user.application.vo.users.UsersAccessTokenVO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||
import cn.iocoder.mall.user.api.MobileCodeService;
|
||||
import cn.iocoder.mall.user.api.OAuth2Service;
|
||||
import cn.iocoder.mall.user.api.UserService;
|
||||
import cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO;
|
||||
import cn.iocoder.mall.user.application.vo.users.MobileRegisterVO;
|
||||
import cn.iocoder.mall.user.application.vo.users.UsersMobileRegisterVO;
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
@@ -44,8 +45,8 @@ public class PassportController {
|
||||
@ApiImplicitParam(name = "mobile", value = "手机号", required = true, example = "15601691300"),
|
||||
@ApiImplicitParam(name = "code", value = "验证码", required = true, example = "9999")
|
||||
})
|
||||
public CommonResult<MobileRegisterVO> mobileRegister(@RequestParam("mobile") String mobile,
|
||||
@RequestParam("code") String code) {
|
||||
public CommonResult<UsersMobileRegisterVO> mobileRegister(@RequestParam("mobile") String mobile,
|
||||
@RequestParam("code") String code) {
|
||||
CommonResult<OAuth2AccessTokenBO> result = oauth2Service.getAccessToken(mobile, code);
|
||||
return PassportConvert.INSTANCE.convert(result);
|
||||
}
|
||||
@@ -74,7 +75,12 @@ public class PassportController {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO 功能:刷新 token
|
||||
@PermitAll
|
||||
@PostMapping("/refresh_token") // TODO 功能:刷新 token
|
||||
public CommonResult<UsersAccessTokenVO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
|
||||
CommonResult<OAuth2AccessTokenBO> result = oauth2Service.refreshToken(refreshToken);
|
||||
return PassportConvert.INSTANCE.convert2(result);
|
||||
}
|
||||
|
||||
// TODO 功能:退出,销毁 token
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ package cn.iocoder.mall.user.application.convert;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO;
|
||||
import cn.iocoder.mall.user.application.vo.users.MobileRegisterVO;
|
||||
import cn.iocoder.mall.user.application.vo.users.UsersAccessTokenVO;
|
||||
import cn.iocoder.mall.user.application.vo.users.UsersMobileRegisterVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
@@ -13,9 +14,12 @@ public interface PassportConvert {
|
||||
PassportConvert INSTANCE = Mappers.getMapper(PassportConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
MobileRegisterVO convert(OAuth2AccessTokenBO oauth2AccessTokenBO);
|
||||
UsersMobileRegisterVO convert(OAuth2AccessTokenBO oauth2AccessTokenBO);
|
||||
|
||||
@Mappings({})
|
||||
CommonResult<MobileRegisterVO> convert(CommonResult<OAuth2AccessTokenBO> oauth2AccessTokenBO);
|
||||
CommonResult<UsersMobileRegisterVO> convert(CommonResult<OAuth2AccessTokenBO> oauth2AccessTokenBO);
|
||||
|
||||
}
|
||||
@Mappings({})
|
||||
CommonResult<UsersAccessTokenVO> convert2(CommonResult<OAuth2AccessTokenBO> result);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.mall.user.application.vo.users;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel("认证令牌 VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UsersAccessTokenVO {
|
||||
|
||||
@ApiModelProperty(value = "访问令牌", required = true, example = "2e3d7635c15e47e997611707a237859f")
|
||||
private String accessToken;
|
||||
@ApiModelProperty(value = "刷新令牌", required = true, example = "d091e7c35bbb4313b0f557a6ef23d033")
|
||||
private String refreshToken;
|
||||
@ApiModelProperty(value = "过期时间,单位:秒", required = true, example = "2879")
|
||||
private Integer expiresIn;
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import lombok.experimental.Accessors;
|
||||
@ApiModel("手机注册结果 VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MobileRegisterVO {
|
||||
public class UsersMobileRegisterVO {
|
||||
|
||||
@ApiModelProperty(value = "访问令牌", required = true, example = "2e3d7635c15e47e997611707a237859f")
|
||||
private String accessToken;
|
||||
@@ -17,8 +17,8 @@ public interface OAuth2Service {
|
||||
*/
|
||||
CommonResult<OAuth2AuthenticationBO> checkToken(String accessToken);
|
||||
|
||||
// TODO @see 刷新 token
|
||||
CommonResult<OAuth2AccessTokenBO> refreshToken(String refreshToken);
|
||||
|
||||
// TODO @see 移除 token
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,13 @@ public enum UserErrorCodeEnum {
|
||||
OAUTH2_INVALID_GRANT_BAD_CREDENTIALS(1001001001, "密码不正确"), // 暂时没用到
|
||||
OAUTH2_INVALID_GRANT_USERNAME_NOT_FOUND(1001001002, "账号不存在"), // 暂时没用到
|
||||
OAUTH2_INVALID_GRANT(1001001010, ""), // 预留
|
||||
OAUTH_INVALID_TOKEN_NOT_FOUND(1001001011, "访问令牌不存在"),
|
||||
OAUTH_INVALID_TOKEN_EXPIRED(1001001012, "访问令牌已过期"),
|
||||
OAUTH_INVALID_TOKEN_INVALID(1001001013, "访问令牌已失效"),
|
||||
OAUTH_INVALID_TOKEN(1001001020, ""), // 预留
|
||||
OAUTH_INVALID_ACCESS_TOKEN_NOT_FOUND(1001001011, "访问令牌不存在"),
|
||||
OAUTH_INVALID_ACCESS_TOKEN_EXPIRED(1001001012, "访问令牌已过期"),
|
||||
OAUTH_INVALID_ACCESS_TOKEN_INVALID(1001001013, "访问令牌已失效"),
|
||||
OAUTH_INVALID_REFRESH_TOKEN(1001001020, ""), // 预留
|
||||
OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND(1001001021, "刷新令牌不存在"),
|
||||
OAUTH_INVALID_REFRESH_TOKEN_EXPIRED(1001001022, "访问令牌已过期"),
|
||||
OAUTH_INVALID_REFRESH_TOKEN_INVALID(1001001023, "刷新令牌已失效"),
|
||||
|
||||
// ========== 用户模块 ==========
|
||||
USER_MOBILE_NOT_REGISTERED(1001002000, "手机号未注册用户"),
|
||||
@@ -54,4 +57,4 @@ public enum UserErrorCodeEnum {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,6 @@ public interface OAuth2AccessTokenMapper {
|
||||
|
||||
void updateToInvalidByUserId(@Param("userId") Integer userId);
|
||||
|
||||
}
|
||||
void updateToInvalidByRefreshToken(@Param("refreshToken") String refreshToken);
|
||||
|
||||
}
|
||||
|
||||
@@ -11,4 +11,6 @@ public interface OAuth2RefreshTokenMapper {
|
||||
|
||||
void updateToInvalidByUserId(@Param("userId") Integer userId);
|
||||
|
||||
}
|
||||
OAuth2RefreshTokenDO selectById(@Param("id") String id);
|
||||
|
||||
}
|
||||
|
||||
@@ -82,18 +82,39 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
public CommonResult<OAuth2AuthenticationBO> checkToken(String accessToken) throws ServiceException {
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByTokenId(accessToken);
|
||||
if (accessTokenDO == null) { // 不存在
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_TOKEN_NOT_FOUND.getCode());
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_ACCESS_TOKEN_NOT_FOUND.getCode());
|
||||
}
|
||||
if (accessTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_TOKEN_EXPIRED.getCode());
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_ACCESS_TOKEN_EXPIRED.getCode());
|
||||
}
|
||||
if (!accessTokenDO.getValid()) { // 无效
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_TOKEN_INVALID.getCode());
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_ACCESS_TOKEN_INVALID.getCode());
|
||||
}
|
||||
// 转换返回
|
||||
return CommonResult.success(OAuth2Convert.INSTANCE.convertToAuthentication(accessTokenDO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<OAuth2AccessTokenBO> refreshToken(String refreshToken) {
|
||||
OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectById(refreshToken);
|
||||
// 校验刷新令牌是否合法
|
||||
if (refreshTokenDO == null) { // 不存在
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND.getCode());
|
||||
}
|
||||
if (refreshTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_REFRESH_TOKEN_EXPIRED.getCode());
|
||||
}
|
||||
if (!refreshTokenDO.getValid()) { // 无效
|
||||
return ServiceExceptionUtil.error(UserErrorCodeEnum.OAUTH_INVALID_REFRESH_TOKEN_INVALID.getCode());
|
||||
}
|
||||
// 标记 refreshToken 对应的 accessToken 都不合法
|
||||
oauth2AccessTokenMapper.updateToInvalidByRefreshToken(refreshToken);
|
||||
// 创建访问令牌
|
||||
OAuth2AccessTokenDO oauth2AccessTokenDO = createOAuth2AccessToken(refreshTokenDO.getUserId(), refreshTokenDO.getId());
|
||||
// 转换返回
|
||||
return CommonResult.success(OAuth2Convert.INSTANCE.convertToAccessTokenWithExpiresIn(oauth2AccessTokenDO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除用户对应的 Token
|
||||
*
|
||||
@@ -134,4 +155,4 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,11 @@
|
||||
AND valid = 1
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
<update id="updateToInvalidByRefreshToken" parameterType="String">
|
||||
UPDATE oauth2_access_token
|
||||
SET valid = 0
|
||||
WHERE refresh_token = #{refreshToken}
|
||||
AND valid = 1
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -17,4 +17,11 @@
|
||||
AND valid = 1
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
<select id="selectById" parameterType="String" resultType="OAuth2RefreshTokenDO">
|
||||
SELECT
|
||||
id, user_id, valid, expires_time, create_time
|
||||
FROM oauth2_refresh_token
|
||||
WHERE id = #{id}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user