Commit 7cb3b4d6 by 段启岩

更改用户token,加注销接口

parent fb774ec5
...@@ -5,6 +5,7 @@ import cn.meteor.beyondclouds.core.interceptor.AccessInterceptor; ...@@ -5,6 +5,7 @@ import cn.meteor.beyondclouds.core.interceptor.AccessInterceptor;
import cn.meteor.beyondclouds.core.interceptor.IpAccessInfoCollectInterceptor; import cn.meteor.beyondclouds.core.interceptor.IpAccessInfoCollectInterceptor;
import cn.meteor.beyondclouds.core.interceptor.ThreadLocalMapInterceptor; import cn.meteor.beyondclouds.core.interceptor.ThreadLocalMapInterceptor;
import cn.meteor.beyondclouds.core.interceptor.TokenInterceptor; import cn.meteor.beyondclouds.core.interceptor.TokenInterceptor;
import cn.meteor.beyondclouds.core.redis.TokenManager;
import cn.meteor.beyondclouds.core.resolver.CurrentSubjectResolver; import cn.meteor.beyondclouds.core.resolver.CurrentSubjectResolver;
import cn.meteor.beyondclouds.core.resolver.CollectAccessInfoResolver; import cn.meteor.beyondclouds.core.resolver.CollectAccessInfoResolver;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -26,9 +27,12 @@ public class WebMvcConfig implements WebMvcConfigurer { ...@@ -26,9 +27,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
@Autowired @Autowired
private IRedisHelper redisHelper; private IRedisHelper redisHelper;
@Autowired
private TokenManager tokenManager;
@Bean @Bean
TokenInterceptor tokenInterceptor() { TokenInterceptor tokenInterceptor() {
return new TokenInterceptor(); return new TokenInterceptor(tokenManager);
} }
@Bean @Bean
......
...@@ -4,6 +4,8 @@ import cn.meteor.beyondclouds.core.authentication.Subject; ...@@ -4,6 +4,8 @@ import cn.meteor.beyondclouds.core.authentication.Subject;
import cn.meteor.beyondclouds.core.constant.HttpRequestHeaderNames; import cn.meteor.beyondclouds.core.constant.HttpRequestHeaderNames;
import cn.meteor.beyondclouds.core.constant.SysConstants; import cn.meteor.beyondclouds.core.constant.SysConstants;
import cn.meteor.beyondclouds.core.emuns.AuthorizationErrorCode; import cn.meteor.beyondclouds.core.emuns.AuthorizationErrorCode;
import cn.meteor.beyondclouds.core.exception.AuthorizationException;
import cn.meteor.beyondclouds.core.redis.TokenManager;
import cn.meteor.beyondclouds.util.JwtUtils; import cn.meteor.beyondclouds.util.JwtUtils;
import cn.meteor.beyondclouds.util.RequestUtils; import cn.meteor.beyondclouds.util.RequestUtils;
import cn.meteor.beyondclouds.util.ThreadLocalMap; import cn.meteor.beyondclouds.util.ThreadLocalMap;
...@@ -26,6 +28,12 @@ public class TokenInterceptor implements HandlerInterceptor { ...@@ -26,6 +28,12 @@ public class TokenInterceptor implements HandlerInterceptor {
private static final String BEARER_AUTHORIZATION_START = "Bearer"; private static final String BEARER_AUTHORIZATION_START = "Bearer";
private TokenManager tokenManager;
public TokenInterceptor(TokenManager tokenManager) {
this.tokenManager = tokenManager;
}
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
...@@ -52,12 +60,12 @@ public class TokenInterceptor implements HandlerInterceptor { ...@@ -52,12 +60,12 @@ public class TokenInterceptor implements HandlerInterceptor {
try { try {
// 获取token // 获取token
String token = authorization.substring(BEARER_AUTHORIZATION_START.length() + 1); String token = authorization.substring(BEARER_AUTHORIZATION_START.length() + 1);
String userId = tokenManager.getUserId(token);
// 校验token if (null == userId) {
Map<String, Claim> claims = JwtUtils.verifyToken(token); throw new AuthorizationException(AuthorizationErrorCode.SIGN_VERIFY_FAILURE);
}
// 构建一个经过系统认证的subject // 构建一个经过系统认证的subject
Subject authenticatedSubject = Subject.authenticated(claims.get(SysConstants.CLAIM_SUBJECT_ID).asString(), RequestUtils.getIpAddr(request)); Subject authenticatedSubject = Subject.authenticated(userId, RequestUtils.getIpAddr(request));
ThreadLocalMap.put(SysConstants.HTTP_ATTRIBUTE_SUBJECT, authenticatedSubject); ThreadLocalMap.put(SysConstants.HTTP_ATTRIBUTE_SUBJECT, authenticatedSubject);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
......
...@@ -81,4 +81,12 @@ public final class RedisKey { ...@@ -81,4 +81,12 @@ public final class RedisKey {
public static String USER_NICK_GEN(String datePrefix) { public static String USER_NICK_GEN(String datePrefix) {
return "USER_NICK_GEN:" + datePrefix; return "USER_NICK_GEN:" + datePrefix;
} }
public static String TOKEN_TO_USER(String token) {
return "TOKEN_TO_USER:" + token;
}
public static String USER_TO_TOKEN(String userId) {
return "USER_TO_TOKEN:" + userId;
}
} }
package cn.meteor.beyondclouds.core.redis;
import cn.meteor.beyondclouds.common.helper.IRedisHelper;
import cn.meteor.beyondclouds.util.UUIDUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author meteor
*/
@Component
public class TokenManager {
private IRedisHelper redisHelper;
@Autowired
public void setRedisHelper(IRedisHelper redisHelper) {
this.redisHelper = redisHelper;
}
/**
* 生成token
* @param userId
* @return
*/
public String generateToken(String userId, int expireSeconds) {
String newToken = UUIDUtils.randomToken();
// 删除旧token
String oldToken = redisHelper.get(RedisKey.USER_TO_TOKEN(userId));
if (oldToken != null) {
redisHelper.del(
RedisKey.TOKEN_TO_USER(oldToken),
RedisKey.USER_TO_TOKEN(userId)
);
}
// 存储新token
redisHelper.set(RedisKey.TOKEN_TO_USER(newToken), userId, expireSeconds);
redisHelper.set(RedisKey.USER_TO_TOKEN(userId), newToken, expireSeconds);
return newToken;
}
/**
* 根据token获取用户ID
* @param token
* @return
*/
public String getUserId(String token) {
return redisHelper.get(RedisKey.TOKEN_TO_USER(token));
}
/**
* 删除token
* @param userId
*/
public void removeToken(String userId) {
// 删除旧token
String oldToken = redisHelper.get(RedisKey.USER_TO_TOKEN(userId));
if (oldToken != null) {
redisHelper.del(
RedisKey.TOKEN_TO_USER(oldToken),
RedisKey.USER_TO_TOKEN(userId)
);
}
}
}
...@@ -10,16 +10,20 @@ import cn.meteor.beyondclouds.core.api.Response; ...@@ -10,16 +10,20 @@ import cn.meteor.beyondclouds.core.api.Response;
import cn.meteor.beyondclouds.core.authentication.Subject; import cn.meteor.beyondclouds.core.authentication.Subject;
import cn.meteor.beyondclouds.core.flow.AccessInfo; import cn.meteor.beyondclouds.core.flow.AccessInfo;
import cn.meteor.beyondclouds.core.flow.ParamType; import cn.meteor.beyondclouds.core.flow.ParamType;
import cn.meteor.beyondclouds.modules.user.dto.UserAuthDTO;
import cn.meteor.beyondclouds.modules.user.dto.UserInfoDTO; import cn.meteor.beyondclouds.modules.user.dto.UserInfoDTO;
import cn.meteor.beyondclouds.modules.user.dto.UserFollowDTO; import cn.meteor.beyondclouds.modules.user.dto.UserFollowDTO;
import cn.meteor.beyondclouds.modules.user.entity.User; import cn.meteor.beyondclouds.modules.user.entity.User;
import cn.meteor.beyondclouds.modules.user.entity.UserBlacklist; import cn.meteor.beyondclouds.modules.user.entity.UserBlacklist;
import cn.meteor.beyondclouds.modules.user.entity.UserStatistics; import cn.meteor.beyondclouds.modules.user.entity.UserStatistics;
import cn.meteor.beyondclouds.modules.user.enums.AccountType;
import cn.meteor.beyondclouds.modules.user.enums.AuthType;
import cn.meteor.beyondclouds.modules.user.exception.UserServiceException; import cn.meteor.beyondclouds.modules.user.exception.UserServiceException;
import cn.meteor.beyondclouds.modules.user.form.*; import cn.meteor.beyondclouds.modules.user.form.*;
import cn.meteor.beyondclouds.modules.user.service.IUserBlacklistService; import cn.meteor.beyondclouds.modules.user.service.IUserBlacklistService;
import cn.meteor.beyondclouds.modules.user.service.IUserFollowService; import cn.meteor.beyondclouds.modules.user.service.IUserFollowService;
import cn.meteor.beyondclouds.modules.user.service.IUserService; import cn.meteor.beyondclouds.modules.user.service.IUserService;
import cn.meteor.beyondclouds.modules.user.vo.UserAuthMapVO;
import cn.meteor.beyondclouds.modules.user.vo.UserInfoWithFollowedVO; import cn.meteor.beyondclouds.modules.user.vo.UserInfoWithFollowedVO;
import cn.meteor.beyondclouds.util.SubjectUtils; import cn.meteor.beyondclouds.util.SubjectUtils;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
...@@ -32,6 +36,9 @@ import org.springframework.validation.BindingResult; ...@@ -32,6 +36,9 @@ import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* @author meteor * @author meteor
...@@ -434,6 +441,13 @@ public class UserApi { ...@@ -434,6 +441,13 @@ public class UserApi {
PageDTO<UserFollowDTO> pageDTO = userService.getActivesUsers(pageForm.getPage(), pageForm.getSize()); PageDTO<UserFollowDTO> pageDTO = userService.getActivesUsers(pageForm.getPage(), pageForm.getSize());
return Response.success(pageDTO); return Response.success(pageDTO);
} }
@ApiOperation(("注销登录"))
@GetMapping("/user/logout")
public Response<UserAuthMapVO> logout(){
userService.logout();
return Response.success();
}
} }
...@@ -139,4 +139,9 @@ public interface IUserService extends IService<User> { ...@@ -139,4 +139,9 @@ public interface IUserService extends IService<User> {
* @return * @return
*/ */
PageDTO<UserFollowDTO> getHotReplies(Integer page, Integer size); PageDTO<UserFollowDTO> getHotReplies(Integer page, Integer size);
/**
* 注销登录
*/
void logout();
} }
...@@ -6,6 +6,7 @@ import cn.meteor.beyondclouds.common.helper.IQQAuthenticationHelper; ...@@ -6,6 +6,7 @@ import cn.meteor.beyondclouds.common.helper.IQQAuthenticationHelper;
import cn.meteor.beyondclouds.common.helper.IRedisHelper; import cn.meteor.beyondclouds.common.helper.IRedisHelper;
import cn.meteor.beyondclouds.core.queue.message.UserActionMessage; import cn.meteor.beyondclouds.core.queue.message.UserActionMessage;
import cn.meteor.beyondclouds.core.redis.RedisKey; import cn.meteor.beyondclouds.core.redis.RedisKey;
import cn.meteor.beyondclouds.core.redis.TokenManager;
import cn.meteor.beyondclouds.modules.queue.service.IMessageQueueService; import cn.meteor.beyondclouds.modules.queue.service.IMessageQueueService;
import cn.meteor.beyondclouds.modules.user.dto.AuthenticationResultDTO; import cn.meteor.beyondclouds.modules.user.dto.AuthenticationResultDTO;
import cn.meteor.beyondclouds.modules.user.dto.UserAuthDTO; import cn.meteor.beyondclouds.modules.user.dto.UserAuthDTO;
...@@ -49,6 +50,8 @@ public class AuthenticationServiceImpl implements IAuthenticationService { ...@@ -49,6 +50,8 @@ public class AuthenticationServiceImpl implements IAuthenticationService {
private IMessageQueueService messageQueueService; private IMessageQueueService messageQueueService;
private TokenManager tokenManager;
@Autowired @Autowired
public AuthenticationServiceImpl(IUserAuthLocalService userAuthLocalService, public AuthenticationServiceImpl(IUserAuthLocalService userAuthLocalService,
IQQAuthenticationHelper iqqAuthenticationHelper, IQQAuthenticationHelper iqqAuthenticationHelper,
...@@ -63,6 +66,11 @@ public class AuthenticationServiceImpl implements IAuthenticationService { ...@@ -63,6 +66,11 @@ public class AuthenticationServiceImpl implements IAuthenticationService {
} }
@Autowired @Autowired
public void setTokenManager(TokenManager tokenManager) {
this.tokenManager = tokenManager;
}
@Autowired
public void setMessageQueueService(IMessageQueueService messageQueueService) { public void setMessageQueueService(IMessageQueueService messageQueueService) {
this.messageQueueService = messageQueueService; this.messageQueueService = messageQueueService;
} }
...@@ -165,10 +173,7 @@ public class AuthenticationServiceImpl implements IAuthenticationService { ...@@ -165,10 +173,7 @@ public class AuthenticationServiceImpl implements IAuthenticationService {
AuthenticationResultDTO result = new AuthenticationResultDTO(); AuthenticationResultDTO result = new AuthenticationResultDTO();
result.setUserId(userId); result.setUserId(userId);
Map<String, String> claimMap = new HashMap<>(1); result.setAccessToken(tokenManager.generateToken(userId, 60 * 30));
claimMap.put("id", userId);
result.setAccessToken(JwtUtils.sign(claimMap));
sendUserLoginMessage(userId); sendUserLoginMessage(userId);
return result; return result;
} }
......
...@@ -8,6 +8,7 @@ import cn.meteor.beyondclouds.common.helper.IRedisHelper; ...@@ -8,6 +8,7 @@ import cn.meteor.beyondclouds.common.helper.IRedisHelper;
import cn.meteor.beyondclouds.core.queue.message.DataItemChangeMessage; import cn.meteor.beyondclouds.core.queue.message.DataItemChangeMessage;
import cn.meteor.beyondclouds.core.queue.message.DataItemType; import cn.meteor.beyondclouds.core.queue.message.DataItemType;
import cn.meteor.beyondclouds.core.redis.RedisKey; import cn.meteor.beyondclouds.core.redis.RedisKey;
import cn.meteor.beyondclouds.core.redis.TokenManager;
import cn.meteor.beyondclouds.modules.mail.dto.EmailDTO; import cn.meteor.beyondclouds.modules.mail.dto.EmailDTO;
import cn.meteor.beyondclouds.modules.mail.service.IMailService; import cn.meteor.beyondclouds.modules.mail.service.IMailService;
import cn.meteor.beyondclouds.modules.mail.util.EmailUtils; import cn.meteor.beyondclouds.modules.mail.util.EmailUtils;
...@@ -63,6 +64,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU ...@@ -63,6 +64,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
private UserNickGenerator userNickGenerator; private UserNickGenerator userNickGenerator;
private IUserFollowService userFollowService; private IUserFollowService userFollowService;
private IMessageQueueService messageQueueService; private IMessageQueueService messageQueueService;
private TokenManager tokenManager;
private static final long MILLS_OF_DAY = 1000 * 60 * 60 * 24; private static final long MILLS_OF_DAY = 1000 * 60 * 60 * 24;
...@@ -75,6 +77,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU ...@@ -75,6 +77,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
} }
@Autowired @Autowired
public void setTokenManager(TokenManager tokenManager) {
this.tokenManager = tokenManager;
}
@Autowired
public void setUserNickGenerator(UserNickGenerator userNickGenerator) { public void setUserNickGenerator(UserNickGenerator userNickGenerator) {
this.userNickGenerator = userNickGenerator; this.userNickGenerator = userNickGenerator;
} }
...@@ -616,6 +623,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU ...@@ -616,6 +623,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
return userFollowDTOPage; return userFollowDTOPage;
} }
@Override
public void logout() {
if (SubjectUtils.isAuthenticated()) {
String userId = (String) SubjectUtils.getSubject().getId();
tokenManager.removeToken(userId);
}
}
private String generateAvatarAndSave(String id) throws IOException, OssException { private String generateAvatarAndSave(String id) throws IOException, OssException {
return ossHelper.upload(AvatarUtils.create(id), "avatar/" + UUIDUtils.randomUUID() + ".png"); return ossHelper.upload(AvatarUtils.create(id), "avatar/" + UUIDUtils.randomUUID() + ".png");
} }
......
package cn.meteor.beyondclouds.util; package cn.meteor.beyondclouds.util;
import java.util.Random;
import java.util.UUID; import java.util.UUID;
/** /**
...@@ -8,6 +9,8 @@ import java.util.UUID; ...@@ -8,6 +9,8 @@ import java.util.UUID;
*/ */
public class UUIDUtils { public class UUIDUtils {
private static final Random rand = new Random();
/** /**
* 生成随机UUID * 生成随机UUID
* @return * @return
...@@ -16,4 +19,24 @@ public class UUIDUtils { ...@@ -16,4 +19,24 @@ public class UUIDUtils {
return UUID.randomUUID().toString().toLowerCase(); return UUID.randomUUID().toString().toLowerCase();
} }
/**
* 生成随机UUID
* @return
*/
public static String randomToken() {
String uuid1 = randomUUID().replace("-", "");
String uuid2 = randomUUID().replace("-", "");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < uuid1.length(); i++) {
int random = rand.nextInt(2);
builder.append(random == 0 ? Character.toUpperCase(uuid1.charAt(i)) : Character.toLowerCase(uuid1.charAt(i)));
}
for (int i = 0; i < uuid2.length(); i++) {
int random = rand.nextInt(2);
builder.append(random == 0 ? Character.toUpperCase(uuid2.charAt(i)) : Character.toLowerCase(uuid2.charAt(i)));
}
return builder.toString();
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment