diff --git a/README.md b/README.md
index 4bd3947..fcaf458 100644
--- a/README.md
+++ b/README.md
@@ -97,7 +97,9 @@ forest([ˈfôrəst],n.森林)是一款现代化的知识社区项目,使
## 鸣谢
- 感谢 `JetBrains` 对本项目的帮助,为作者提供了开源许可版 `JetBrains` 全家桶
-![JetBrains](src/main/resources/static/jetbrains.png)
+
+![JetBrains](src/main/resources/static/jb_beam.svg)
+
## ⭐ Star 历史
diff --git a/pom.xml b/pom.xml
index 90e594e..b9014d4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -128,7 +128,7 @@
com.alibaba
fastjson
- 2.0.15
+ 2.0.16
@@ -147,6 +147,12 @@
commons-collections4
4.4
+
+
+ com.github.f4b6a3
+ ulid-creator
+ 5.1.0
+
commons-lang
@@ -177,7 +183,7 @@
com.alibaba
druid-spring-boot-starter
- 1.2.13-SNSAPSHOT
+ 1.2.14
org.apache.logging.log4j
@@ -255,12 +261,12 @@
cn.hutool
hutool-core
- 5.8.8
+ 5.8.9
cn.hutool
hutool-http
- 5.8.8
+ 5.8.9
diff --git a/src/main/java/com/rymcu/forest/auth/BaseHashedCredentialsMatcher.java b/src/main/java/com/rymcu/forest/auth/BaseHashedCredentialsMatcher.java
new file mode 100644
index 0000000..9b82351
--- /dev/null
+++ b/src/main/java/com/rymcu/forest/auth/BaseHashedCredentialsMatcher.java
@@ -0,0 +1,31 @@
+package com.rymcu.forest.auth;
+
+import com.rymcu.forest.dto.TokenUser;
+import com.rymcu.forest.util.UserUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.apache.shiro.authz.UnauthenticatedException;
+
+import java.util.Objects;
+
+/**
+ * @author ronger
+ */
+public class BaseHashedCredentialsMatcher extends HashedCredentialsMatcher {
+
+ @Override
+ public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
+ TokenModel tokenModel = (TokenModel) token;
+ String accessToken = (String) tokenModel.getCredentials();
+ if (StringUtils.isBlank(accessToken)) {
+ throw new UnauthenticatedException();
+ }
+ TokenUser tokenUser = UserUtils.getTokenUser(accessToken);
+ if (Objects.isNull(tokenUser)) {
+ throw new UnauthenticatedException();
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/com/rymcu/forest/jwt/def/JwtConstants.java b/src/main/java/com/rymcu/forest/auth/JwtConstants.java
similarity index 73%
rename from src/main/java/com/rymcu/forest/jwt/def/JwtConstants.java
rename to src/main/java/com/rymcu/forest/auth/JwtConstants.java
index 62162fe..01cf63b 100644
--- a/src/main/java/com/rymcu/forest/jwt/def/JwtConstants.java
+++ b/src/main/java/com/rymcu/forest/auth/JwtConstants.java
@@ -1,21 +1,26 @@
-package com.rymcu.forest.jwt.def;
+package com.rymcu.forest.auth;
/**
* @author ronger
*/
public class JwtConstants {
+
+
/**
* 上线需要变更
*/
public static final String JWT_SECRET = "JYJ5Qv2WF4lA6jPl5GKuAG";
-
+
public static final String AUTHORIZATION = "Authorization";
public static final String UPLOAD_TOKEN = "X-Upload-Token";
public static final String CURRENT_USER_NAME = "CURRENT_TOKEN_USER_NAME";
public static final String CURRENT_TOKEN_CLAIMS = "CURRENT_TOKEN_CLAIMS";
public static final String LAST_ONLINE = "last_online:";
- public static final long TOKEN_EXPIRES_HOUR = 2 * 60;
+
+ public static final long TOKEN_EXPIRES_HOUR = 2;
public static final long LAST_ONLINE_EXPIRES_MINUTE = 10;
+ public static final long TOKEN_EXPIRES_MINUTE = 15;
+ public static final long REFRESH_TOKEN_EXPIRES_HOUR = 2;
}
diff --git a/src/main/java/com/rymcu/forest/auth/JwtFilter.java b/src/main/java/com/rymcu/forest/auth/JwtFilter.java
new file mode 100644
index 0000000..f184811
--- /dev/null
+++ b/src/main/java/com/rymcu/forest/auth/JwtFilter.java
@@ -0,0 +1,118 @@
+package com.rymcu.forest.auth;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.authz.UnauthenticatedException;
+import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Created on 2022/10/27 19:58.
+ *
+ * @author ronger
+ * @email ronger-x@outlook.com
+ * @desc : com.rymcu.forest.auth
+ */
+@Slf4j
+public class JwtFilter extends BasicHttpAuthenticationFilter {
+ /**
+ * 判断用户是否想要登入。
+ * 检测 header 里面是否包含 Authorization 字段即可
+ */
+ @Override
+ protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
+ HttpServletRequest req = (HttpServletRequest) request;
+ String authorization = req.getHeader(JwtConstants.AUTHORIZATION);
+ return authorization != null;
+ }
+
+ /**
+ *
+ */
+ @Override
+ protected boolean executeLogin(ServletRequest request, ServletResponse response) {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+ String authorization = httpServletRequest.getHeader(JwtConstants.AUTHORIZATION);
+ // 验证token
+ Claims claims;
+ try {
+ claims = Jwts.parser().setSigningKey(JwtConstants.JWT_SECRET).parseClaimsJws(authorization).getBody();
+ } catch (final SignatureException e) {
+ throw new UnauthenticatedException();
+ }
+ Object username = claims.getId();
+ if (Objects.isNull(username)) {
+ throw new UnauthenticatedException();
+ }
+ TokenModel token = new TokenModel(username.toString(), authorization);
+ // 提交给realm进行登入,如果错误他会抛出异常并被捕获
+ getSubject(request, response).login(token);
+ // 如果没有抛出异常则代表登入成功,返回true
+ return true;
+ }
+
+ /**
+ * 这里我们详细说明下为什么最终返回的都是true,即允许访问
+ * 例如我们提供一个地址 GET /article
+ * 登入用户和游客看到的内容是不同的
+ * 如果在这里返回了false,请求会被直接拦截,用户看不到任何东西
+ * 所以我们在这里返回true,Controller中可以通过 subject.isAuthenticated() 来判断用户是否登入
+ * 如果有些资源只有登入用户才能访问,我们只需要在方法上面加上 @RequiresAuthentication 注解即可
+ * 但是这样做有一个缺点,就是不能够对GET,POST等请求进行分别过滤鉴权(因为我们重写了官方的方法),但实际上对应用影响不大
+ */
+ @Override
+ protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
+ if (isLoginAttempt(request, response)) {
+ try {
+ executeLogin(request, response);
+ } catch (Exception e) {
+ response401(request, response);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 对跨域提供支持
+ */
+ @Override
+ protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+ HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+ httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
+ httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
+ httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control" +
+ "-Request-Headers"));
+ // 跨域时会首先发送一个 option 请求,这里我们给 option 请求直接返回正常状态
+ if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
+ httpServletResponse.setStatus(HttpStatus.OK.value());
+ return false;
+ }
+ return super.preHandle(request, response);
+ }
+
+ /**
+ * 将非法请求跳转到 /401
+ */
+ private void response401(ServletRequest request, ServletResponse response) {
+ try {
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ httpResponse.setContentType("application/json;charset=utf-8");
+ httpResponse.getOutputStream().write("login fail".getBytes());
+ } catch (IOException e) {
+ // 错误日志
+ log.error(e.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/com/rymcu/forest/auth/JwtRealm.java b/src/main/java/com/rymcu/forest/auth/JwtRealm.java
new file mode 100644
index 0000000..859898e
--- /dev/null
+++ b/src/main/java/com/rymcu/forest/auth/JwtRealm.java
@@ -0,0 +1,75 @@
+package com.rymcu.forest.auth;
+
+import com.rymcu.forest.dto.TokenUser;
+import com.rymcu.forest.entity.Role;
+import com.rymcu.forest.entity.User;
+import com.rymcu.forest.service.RoleService;
+import com.rymcu.forest.util.UserUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * Created on 2022/10/27 20:04.
+ *
+ * @author ronger
+ * @email ronger-x@outlook.com
+ * @desc : com.rymcu.forest.auth
+ */
+public class JwtRealm extends AuthorizingRealm {
+ @Resource
+ private RoleService roleService;
+
+ @Resource
+ private TokenManager manager;
+
+
+ @Override
+ public boolean supports(AuthenticationToken token) {
+ return token instanceof TokenModel;
+ }
+
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
+ String accessToken = (String) principals.getPrimaryPrincipal();
+ TokenUser tokenUser = UserUtils.getTokenUser(accessToken);
+ SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
+ User user = new User();
+ user.setIdUser(tokenUser.getIdUser());
+ try {
+ List roles = roleService.selectRoleByUser(user);
+ for (Role role : roles) {
+ if (StringUtils.isNotBlank(role.getInputCode())) {
+ authorizationInfo.addRole(role.getInputCode());
+ authorizationInfo.addStringPermission(role.getInputCode());
+ }
+ }
+ // 添加用户权限
+ authorizationInfo.addStringPermission("user");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return authorizationInfo;
+ }
+
+ /**
+ * 认证回调函数, 登录时调用,主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。
+ */
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {
+ TokenModel token = (TokenModel) authToken;
+ if (!manager.checkToken(token)) {
+ throw new AuthenticationException();
+ }
+ return new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), this.getName());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/rymcu/forest/jwt/service/RedisTokenManager.java b/src/main/java/com/rymcu/forest/auth/RedisTokenManager.java
similarity index 86%
rename from src/main/java/com/rymcu/forest/jwt/service/RedisTokenManager.java
rename to src/main/java/com/rymcu/forest/auth/RedisTokenManager.java
index a409a01..a5a7f80 100644
--- a/src/main/java/com/rymcu/forest/jwt/service/RedisTokenManager.java
+++ b/src/main/java/com/rymcu/forest/auth/RedisTokenManager.java
@@ -1,9 +1,7 @@
-package com.rymcu.forest.jwt.service;
+package com.rymcu.forest.auth;
import com.rymcu.forest.handler.event.AccountEvent;
-import com.rymcu.forest.jwt.def.JwtConstants;
-import com.rymcu.forest.jwt.model.TokenModel;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang.StringUtils;
@@ -38,7 +36,7 @@ public class RedisTokenManager implements TokenManager {
//使用 account 作为源 token
String token = Jwts.builder().setId(id).setSubject(id).setIssuedAt(new Date()).signWith(SignatureAlgorithm.HS256, JwtConstants.JWT_SECRET).compact();
//存储到 redis 并设置过期时间
- redisTemplate.boundValueOps(id).set(token, JwtConstants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
+ redisTemplate.boundValueOps(id).set(token, JwtConstants.TOKEN_EXPIRES_MINUTE, TimeUnit.MINUTES);
return token;
}
@@ -56,8 +54,6 @@ public class RedisTokenManager implements TokenManager {
if (token == null || !token.equals(model.getToken())) {
return false;
}
- // 如果验证成功,说明此用户进行了一次有效操作,延长 token 的过期时间
- redisTemplate.boundValueOps(model.getUsername()).expire(JwtConstants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
StringBuilder key = new StringBuilder();
key.append(JwtConstants.LAST_ONLINE).append(model.getUsername());
String result = redisTemplate.boundValueOps(key.toString()).get();
diff --git a/src/main/java/com/rymcu/forest/jwt/service/TokenManager.java b/src/main/java/com/rymcu/forest/auth/TokenManager.java
similarity index 87%
rename from src/main/java/com/rymcu/forest/jwt/service/TokenManager.java
rename to src/main/java/com/rymcu/forest/auth/TokenManager.java
index 66ac47d..5b62e0c 100644
--- a/src/main/java/com/rymcu/forest/jwt/service/TokenManager.java
+++ b/src/main/java/com/rymcu/forest/auth/TokenManager.java
@@ -1,7 +1,4 @@
-package com.rymcu.forest.jwt.service;
-
-
-import com.rymcu.forest.jwt.model.TokenModel;
+package com.rymcu.forest.auth;
/**
* 对token进行操作的接口
@@ -12,6 +9,7 @@ public interface TokenManager {
/**
* 创建一个token关联上指定用户
+ * @param id
* @return 生成的token
*/
public String createToken(String id);
@@ -25,6 +23,8 @@ public interface TokenManager {
/**
* 从字符串中解析token
+ * @param token
+ * @param account
* @return
*/
public TokenModel getToken(String token, String account);
diff --git a/src/main/java/com/rymcu/forest/jwt/model/TokenModel.java b/src/main/java/com/rymcu/forest/auth/TokenModel.java
similarity index 61%
rename from src/main/java/com/rymcu/forest/jwt/model/TokenModel.java
rename to src/main/java/com/rymcu/forest/auth/TokenModel.java
index 55918c6..beb44ad 100644
--- a/src/main/java/com/rymcu/forest/jwt/model/TokenModel.java
+++ b/src/main/java/com/rymcu/forest/auth/TokenModel.java
@@ -1,16 +1,22 @@
-package com.rymcu.forest.jwt.model;
+package com.rymcu.forest.auth;
+
+import org.apache.shiro.authc.AuthenticationToken;
/**
* Token的Model类,可以增加字段提高安全性,例如时间戳、url签名
* @author ScienJus
* @date 2015/7/31.
*/
-public class TokenModel {
+public class TokenModel implements AuthenticationToken {
private String username;
private String token;
+ public TokenModel(String token) {
+ this.token = token;
+ }
+
public TokenModel(String username, String token) {
this.username = username;
this.token = token;
@@ -31,4 +37,14 @@ public class TokenModel {
public void setToken(String token) {
this.token = token;
}
+
+ @Override
+ public Object getPrincipal() {
+ return token;
+ }
+
+ @Override
+ public Object getCredentials() {
+ return token;
+ }
}
diff --git a/src/main/java/com/rymcu/forest/config/BaseSessionManager.java b/src/main/java/com/rymcu/forest/config/BaseSessionManager.java
deleted file mode 100644
index 7d76213..0000000
--- a/src/main/java/com/rymcu/forest/config/BaseSessionManager.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.rymcu.forest.config;
-
-import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
-import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
-import org.apache.shiro.web.util.WebUtils;
-import org.springframework.util.StringUtils;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import java.io.Serializable;
-
-/**
- * @author ronger
- */
-public class BaseSessionManager extends DefaultWebSessionManager {
- private static final String AUTHORIZATION = "Authorization";
-
- private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
-
- public BaseSessionManager() {
- super();
- }
-
- @Override
- protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
- String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
- // 如果请求头中有 Authorization 则其值为 sessionId
- if (!StringUtils.isEmpty(id)) {
- request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
- request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
- request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
-
- return id;
- } else {
- // 否则按默认规则从 cookie 取 sessionId
- return super.getSessionId(request, response);
- }
- }
-}
diff --git a/src/main/java/com/rymcu/forest/config/BaseShiroFilterFactoryBean.java b/src/main/java/com/rymcu/forest/config/BaseShiroFilterFactoryBean.java
deleted file mode 100644
index 8215885..0000000
--- a/src/main/java/com/rymcu/forest/config/BaseShiroFilterFactoryBean.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.rymcu.forest.config;
-
-import org.apache.shiro.mgt.SecurityManager;
-import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
-import org.apache.shiro.web.filter.mgt.FilterChainManager;
-import org.apache.shiro.web.filter.mgt.FilterChainResolver;
-import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
-import org.apache.shiro.web.mgt.WebSecurityManager;
-import org.apache.shiro.web.servlet.AbstractShiroFilter;
-import org.springframework.beans.factory.BeanInitializationException;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * @author ronger
- * Shiro静态资源配置
- * */
-public class BaseShiroFilterFactoryBean extends ShiroFilterFactoryBean {
-
- private Set ignoreExt;
-
- public BaseShiroFilterFactoryBean() {
- super();
- ignoreExt = new HashSet<>();
- ignoreExt.add(".svg");
- ignoreExt.add(".jpg");
- ignoreExt.add(".png");
- ignoreExt.add(".gif");
- ignoreExt.add(".bmp");
- ignoreExt.add(".js");
- ignoreExt.add(".css");
- }
-
- @Override
- protected AbstractShiroFilter createInstance() throws Exception {
-
- SecurityManager securityManager = getSecurityManager();
- if (securityManager == null) {
- String msg = "SecurityManager property must be set.";
- throw new BeanInitializationException(msg);
- }
-
- if (!(securityManager instanceof WebSecurityManager)) {
- String msg = "The security manager does not implement the WebSecurityManager interface.";
- throw new BeanInitializationException(msg);
- }
-
- FilterChainManager manager = createFilterChainManager();
-
- PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
- chainResolver.setFilterChainManager(manager);
-
- return new BaseSpringShiroFilter((WebSecurityManager) securityManager, chainResolver);
- }
-
- private final class BaseSpringShiroFilter extends AbstractShiroFilter {
-
- protected BaseSpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
- super();
- if (webSecurityManager == null) {
- throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
- }
- setSecurityManager(webSecurityManager);
- if (resolver != null) {
- setFilterChainResolver(resolver);
- }
- }
-
- @Override
- protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse,
- FilterChain chain) throws ServletException, IOException {
- HttpServletRequest request = (HttpServletRequest)servletRequest;
- String str = request.getRequestURI().toLowerCase();
- // 因为ShiroFilter 拦截所有请求(在上面我们配置了urlPattern 为 * ,当然你也可以在那里精确的添加要处理的路径,这样就不需要这个类了),而在每次请求里面都做了session的读取和更新访问时间等操作,这样在集群部署session共享的情况下,数量级的加大了处理量负载。
- // 所以我们这里将一些能忽略的请求忽略掉。
- // 当然如果你的集群系统使用了动静分离处理,静态资料的请求不会到Filter这个层面,便可以忽略。
- boolean flag = true;
- int idx = 0;
- if(( idx = str.indexOf(".")) > 0){
- str = str.substring(idx);
- if(ignoreExt.contains(str.toLowerCase())) {
- flag = false;
- }
- }
- if(flag){
- super.doFilterInternal(servletRequest, servletResponse, chain);
- }else{
- chain.doFilter(servletRequest, servletResponse);
- }
- }
-
- }
-}
diff --git a/src/main/java/com/rymcu/forest/config/BaseShiroRealm.java b/src/main/java/com/rymcu/forest/config/BaseShiroRealm.java
deleted file mode 100644
index 2ddf682..0000000
--- a/src/main/java/com/rymcu/forest/config/BaseShiroRealm.java
+++ /dev/null
@@ -1,158 +0,0 @@
-package com.rymcu.forest.config;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.rymcu.forest.core.constant.ShiroConstants;
-import com.rymcu.forest.core.exception.CaptchaException;
-import com.rymcu.forest.entity.Permission;
-import com.rymcu.forest.entity.Role;
-import com.rymcu.forest.entity.User;
-import com.rymcu.forest.service.PermissionService;
-import com.rymcu.forest.service.RoleService;
-import com.rymcu.forest.service.UserService;
-import com.rymcu.forest.util.Encodes;
-import com.rymcu.forest.util.Utils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.exceptions.TooManyResultsException;
-import org.apache.shiro.authc.*;
-import org.apache.shiro.authz.AuthorizationInfo;
-import org.apache.shiro.authz.SimpleAuthorizationInfo;
-import org.apache.shiro.realm.AuthorizingRealm;
-import org.apache.shiro.subject.PrincipalCollection;
-import org.apache.shiro.util.ByteSource;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import javax.annotation.Resource;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author ronger
- * @since 2018/05/28 11:00
- * 自定义权限匹配和账号密码匹配
- */
-public class BaseShiroRealm extends AuthorizingRealm {
- @Resource
- private RoleService roleService;
-
- @Resource
- private PermissionService permissionService;
-
- @Resource
- private UserService userService;
-
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
- Principal principal = (Principal) principals.getPrimaryPrincipal();
- User user = new User();
- user.setIdUser(principal.getId());
- try {
- List roles = roleService.selectRoleByUser(user);
- for (Role role : roles) {
- if (StringUtils.isNotBlank(role.getInputCode())) {
- authorizationInfo.addRole(role.getInputCode());
- }
- }
- List permissions = permissionService.selectPermissionByUser(user);
- for (Permission perm : permissions) {
- if (perm.getPermissionCategory() != null) {
- authorizationInfo.addStringPermission(perm.getPermissionCategory());
- }
- }
- // 添加用户权限
- authorizationInfo.addStringPermission("user");
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- return authorizationInfo;
- }
-
- /**
- * 认证回调函数, 登录时调用,主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。
- */
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
- UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
- //获取用户的输入的账号.
- String username = token.getUsername();
-
- User user = null;
- ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- if (!org.springframework.util.StringUtils.isEmpty(attributes.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA))) {
- throw new CaptchaException();
- }
- try {
- user = userService.findByAccount(username);
- } catch (TooManyResultsException e) {
- e.printStackTrace();
- }
- if (user == null) {
- return null;
- }
- // 账户冻结(是否允许登陆)
- if (!"0".equals(user.getStatus())) {
- throw new LockedAccountException();
- }
- byte[] salt = Encodes.decodeHex(user.getPassword().substring(0, 16));
- return new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin()),
- user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
- }
-
- /**
- * 授权用户信息
- */
- public static class Principal implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- @JsonFormat(shape = JsonFormat.Shape.STRING)
- private Long id; // 编号
- private String account; // 登录名
- private String name; // 姓名
- private boolean mobileLogin; // 是否手机登录
-
-// private Map cacheMap;
-
- public Principal(User user, boolean mobileLogin) {
- this.id = user.getIdUser();
- this.account = user.getAccount();
- this.name = user.getNickname();
- this.mobileLogin = mobileLogin;
- }
-
- public Long getId() {
- return id;
- }
-
- public String getAccount() {
- return account;
- }
-
- public String getName() {
- return name;
- }
-
- public boolean isMobileLogin() {
- return mobileLogin;
- }
-
- /**
- * 获取SESSIONID
- */
- public String getSessionid() {
- try {
- return (String) Utils.getSession().getId();
- } catch (Exception e) {
- return "";
- }
- }
-
- @Override
- public String toString() {
- return id.toString();
- }
-
- }
-}
diff --git a/src/main/java/com/rymcu/forest/config/MybatisConfigurer.java b/src/main/java/com/rymcu/forest/config/MybatisConfigurer.java
index 73aede7..7292eda 100644
--- a/src/main/java/com/rymcu/forest/config/MybatisConfigurer.java
+++ b/src/main/java/com/rymcu/forest/config/MybatisConfigurer.java
@@ -1,7 +1,6 @@
package com.rymcu.forest.config;
import com.github.pagehelper.PageInterceptor;
-import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
diff --git a/src/main/java/com/rymcu/forest/config/RedisKeyExpirationListener.java b/src/main/java/com/rymcu/forest/config/RedisKeyExpirationListener.java
index ce81763..7b358e0 100644
--- a/src/main/java/com/rymcu/forest/config/RedisKeyExpirationListener.java
+++ b/src/main/java/com/rymcu/forest/config/RedisKeyExpirationListener.java
@@ -1,7 +1,6 @@
package com.rymcu.forest.config;
-import com.rymcu.forest.entity.User;
-import com.rymcu.forest.jwt.def.JwtConstants;
+import com.rymcu.forest.auth.JwtConstants;
import com.rymcu.forest.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -40,14 +39,13 @@ public class RedisKeyExpirationListener extends KeyExpirationEventMessageListene
*/
@Override
public void onMessage(Message message, byte[] pattern) {
-
// 获取到失效的 key
String expiredKey = message.toString();
if (expiredKey.contains(JwtConstants.LAST_ONLINE)) {
- String email = expiredKey.replace(JwtConstants.LAST_ONLINE, "");
+ String account = expiredKey.replace(JwtConstants.LAST_ONLINE, "");
log.info("拿到过期的数据:{}", expiredKey);
- log.info("处理后的数据:{}", email);
- userService.updateLastOnlineTimeByEmail(email);
+ log.info("处理后的数据:{}", account);
+ userService.updateLastOnlineTimeByAccount(account);
}
super.onMessage(message, pattern);
}
diff --git a/src/main/java/com/rymcu/forest/config/ShiroConfig.java b/src/main/java/com/rymcu/forest/config/ShiroConfig.java
index 47463c3..2c78f14 100644
--- a/src/main/java/com/rymcu/forest/config/ShiroConfig.java
+++ b/src/main/java/com/rymcu/forest/config/ShiroConfig.java
@@ -1,20 +1,17 @@
package com.rymcu.forest.config;
-import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import com.rymcu.forest.auth.BaseHashedCredentialsMatcher;
+import com.rymcu.forest.auth.JwtFilter;
+import com.rymcu.forest.auth.JwtRealm;
import org.apache.shiro.mgt.SecurityManager;
-import org.apache.shiro.session.mgt.SessionManager;
-import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
-import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.EnvironmentAware;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
+import org.springframework.context.annotation.DependsOn;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
@@ -24,108 +21,46 @@ import java.util.Map;
* @author ronger
*/
@Configuration
-@ConfigurationProperties(prefix = "redis.shiro")
-public class ShiroConfig implements EnvironmentAware {
-
- private Environment env;
-
- @Override
- public void setEnvironment(Environment environment) {
- this.env=environment;
- }
+public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
- ShiroFilterFactoryBean shiroFilterFactoryBean = new BaseShiroFilterFactoryBean();
+ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
+ //添加自定义的过滤器
+ LinkedHashMap linkedHashMap = new LinkedHashMap<>();
+ linkedHashMap.put("jwt", new JwtFilter());
+ shiroFilterFactoryBean.setFilters(linkedHashMap);
Map filterChainDefinitionMap = new LinkedHashMap();
- //注意过滤器配置顺序 不能颠倒
- //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了,登出后跳转配置的loginUrl
- filterChainDefinitionMap.put("/logout", "logout");
- // 配置不会被拦截的链接 顺序判断
- filterChainDefinitionMap.put("/druid/**", "anon");
- filterChainDefinitionMap.put("/css/**", "anon");
- filterChainDefinitionMap.put("/fonts/**", "anon");
- filterChainDefinitionMap.put("/js/**", "anon");
- filterChainDefinitionMap.put("/uploadFile/**", "anon");
- filterChainDefinitionMap.put("/login", "anon");
-
- filterChainDefinitionMap.put("/api/**", "anon");
- filterChainDefinitionMap.put("/ws/**", "anon");
- filterChainDefinitionMap.put("/wss/**", "anon");
- filterChainDefinitionMap.put("/wx/**", "anon");
- filterChainDefinitionMap.put("/**", "auth");
- //配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据
- shiroFilterFactoryBean.setLoginUrl("/login");
- // 登录成功后要跳转的链接
- shiroFilterFactoryBean.setSuccessUrl("/index");
- //未授权界面;
- shiroFilterFactoryBean.setUnauthorizedUrl("/403");
- shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
-
- Map filtersMap = new LinkedHashMap<>();
- filtersMap.put("auth", baseFormAuthenticationFilter());
- shiroFilterFactoryBean.setFilters(filtersMap);
-
- filterChainDefinitionMap.put("/**", "auth");
+ filterChainDefinitionMap.put("/api/v1/console/**", "anon");
+ filterChainDefinitionMap.put("/api/v1/open-data/**", "anon");
+ filterChainDefinitionMap.put("/**", "jwt");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
- /**
- * 凭证匹配器
- * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
- * )
- *
- * @return
- */
@Bean
- public HashedCredentialsMatcher hashedCredentialsMatcher() {
- HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
- // 散列算法:这里使用MD5算法;
- hashedCredentialsMatcher.setHashAlgorithmName("SHA-1");
- // 散列的次数,比如散列两次,相当于 md5(md5(""));
- hashedCredentialsMatcher.setHashIterations(1024);
- return hashedCredentialsMatcher;
- }
-
- @Bean
- public BaseShiroRealm baseShiroRealm() {
- BaseShiroRealm shiroRealm = new BaseShiroRealm();
- shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
+ public JwtRealm baseShiroRealm() {
+ JwtRealm shiroRealm = new JwtRealm();
+ shiroRealm.setCredentialsMatcher(new BaseHashedCredentialsMatcher());
return shiroRealm;
}
-
- @Bean
- public SecurityManager securityManager() {
- DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
- securityManager.setRealm(baseShiroRealm());
- // 自定义session管理 使用redis
- securityManager.setSessionManager(sessionManager());
- return securityManager;
- }
-
- /**
- * 自定义sessionManager
+ /***
+ * 配置安全管理器
* */
@Bean
- public SessionManager sessionManager() {
- BaseSessionManager sessionManager = new BaseSessionManager();
- sessionManager.setSessionDAO(new MemorySessionDAO());
- sessionManager.setSessionIdUrlRewritingEnabled(false);
- sessionManager.setGlobalSessionTimeout(21600000L);
- return sessionManager;
+ public SecurityManager securityManager() {
+ DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
+ defaultWebSecurityManager.setRealm(baseShiroRealm());
+ return defaultWebSecurityManager;
}
/**
* 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;
- *
- * @param securityManager
- * @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
@@ -136,37 +71,17 @@ public class ShiroConfig implements EnvironmentAware {
/**
* Shiro生命周期处理器
- * @return
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
- /**
- * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
- * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
- *
- * @return
- */
@Bean
- public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
- AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
- authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
- return authorizationAttributeSourceAdvisor;
- }
-
- public FormAuthenticationFilter baseFormAuthenticationFilter(){
- FormAuthenticationFilter formAuthenticationFilter = new ShiroLoginFilter();
- return formAuthenticationFilter;
- }
-
- @Bean
- public FilterRegistrationBean someFilterRegistration() {
- FilterRegistrationBean registration = new FilterRegistrationBean();
- FormAuthenticationFilter baseFormAuthenticationFilter = new ShiroLoginFilter();
- registration.setFilter(baseFormAuthenticationFilter);
- registration.setEnabled(false);
- return registration;
+ @DependsOn({"lifecycleBeanPostProcessor"})
+ public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
+ DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
+ advisorAutoProxyCreator.setProxyTargetClass(true);
+ return advisorAutoProxyCreator;
}
}
diff --git a/src/main/java/com/rymcu/forest/config/ShiroLoginFilter.java b/src/main/java/com/rymcu/forest/config/ShiroLoginFilter.java
deleted file mode 100644
index babf323..0000000
--- a/src/main/java/com/rymcu/forest/config/ShiroLoginFilter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.rymcu.forest.config;
-
-
-import com.alibaba.fastjson.JSONObject;
-import com.alibaba.fastjson.serializer.SerializerFeature;
-import com.rymcu.forest.core.result.GlobalResultGenerator;
-import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- *
- * @author wanwh
- * @date 2019/1/24 0024
- */
-public class ShiroLoginFilter extends FormAuthenticationFilter {
-
- private static final Logger log = LoggerFactory.getLogger(FormAuthenticationFilter.class);
-
- /**
- * 在访问controller前判断是否登录,返回json,不进行重定向。
- * @param request
- * @param response
- * @return true-继续往下执行,false-该filter过滤器已经处理,不继续执行其他过滤器
- * @throws Exception
- */
-
- @Override
- protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
- HttpServletResponse httpServletResponse = (HttpServletResponse) response;
- if (this.isLoginRequest(request, response)) {
- if (this.isLoginSubmission(request, response)) {
- if (log.isTraceEnabled()) {
- log.trace("Login submission detected. Attempting to execute login.");
- }
-
- return this.executeLogin(request, response);
- } else {
- if (log.isTraceEnabled()) {
- log.trace("Login page view.");
- }
-
- return true;
- }
- }else if(isAjax((HttpServletRequest) request)){
- httpServletResponse.setContentType("application/json");
- httpServletResponse.setCharacterEncoding("UTF-8");
- httpServletResponse.setHeader("sessionstatus", "timeOut");
- httpServletResponse.addHeader("loginPath", this.getLoginUrl());
- httpServletResponse.getWriter().write(JSONObject.toJSONString(GlobalResultGenerator.genErrorResult("未登录或已登录超时,请重新登录"), SerializerFeature.PrettyFormat));
- return false;
- }else {
- if (log.isTraceEnabled()) {
- log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [" + this.getLoginUrl() + "]");
- }
-
- this.saveRequestAndRedirectToLogin(request, response);
- return false;
- }
- }
-
- private boolean isAjax(HttpServletRequest request) {
- String requestedWith = request.getHeader("x-requested-with");
- if (requestedWith != null && requestedWith.equalsIgnoreCase("XMLHttpRequest")) {
- return true;
- } else {
- return false;
- }
- }
-}
diff --git a/src/main/java/com/rymcu/forest/config/UsernamePasswordToken.java b/src/main/java/com/rymcu/forest/config/UsernamePasswordToken.java
deleted file mode 100644
index 3225b52..0000000
--- a/src/main/java/com/rymcu/forest/config/UsernamePasswordToken.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.rymcu.forest.config;
-
-/**
- * 用户和密码(包含验证码)令牌类
- * @author ronger
- */
-public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {
-
- private static final long serialVersionUID = 1L;
-
- private String captcha;
- private boolean mobileLogin;
-
- public UsernamePasswordToken() {
- super();
- }
-
- public UsernamePasswordToken(String username, char[] password,
- boolean rememberMe, String host, String captcha, boolean mobileLogin) {
- super(username, password, rememberMe, host);
- this.captcha = captcha;
- this.mobileLogin = mobileLogin;
- }
-
- public String getCaptcha() {
- return captcha;
- }
-
- public void setCaptcha(String captcha) {
- this.captcha = captcha;
- }
-
- public boolean isMobileLogin() {
- return mobileLogin;
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/com/rymcu/forest/config/WebMvcConfigurer.java b/src/main/java/com/rymcu/forest/config/WebMvcConfigurer.java
index b14d7d2..30c9cbe 100644
--- a/src/main/java/com/rymcu/forest/config/WebMvcConfigurer.java
+++ b/src/main/java/com/rymcu/forest/config/WebMvcConfigurer.java
@@ -4,17 +4,14 @@ package com.rymcu.forest.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
-import com.rymcu.forest.jwt.aop.RestAuthTokenInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.ResourceUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@@ -60,22 +57,6 @@ public class WebMvcConfigurer extends WebMvcConfigurationSupport {
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH");
}
- @Bean
- public RestAuthTokenInterceptor restAuthTokenInterceptor() {
- return new RestAuthTokenInterceptor();
- }
-
- /**
- * 添加拦截器
- */
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(restAuthTokenInterceptor()).addPathPatterns("/api/**")
- .excludePathPatterns("/api/v1/console/**", "/api/v1/article/articles/**", "/api/v1/article/detail/**"
- , "/api/v1/topic/**", "/api/v1/user/**", "/api/v1/article/*/comments", "/api/v1/rule/currency/**", "/api/v1/lucene/**", "/api/v1/open-data/**");
-
- }
-
/**
* 访问静态资源
*/
diff --git a/src/main/java/com/rymcu/forest/core/service/log/TransactionAspect.java b/src/main/java/com/rymcu/forest/core/service/log/TransactionAspect.java
index 0f017c0..9da7487 100644
--- a/src/main/java/com/rymcu/forest/core/service/log/TransactionAspect.java
+++ b/src/main/java/com/rymcu/forest/core/service/log/TransactionAspect.java
@@ -2,12 +2,10 @@ package com.rymcu.forest.core.service.log;
import com.rymcu.forest.core.result.GlobalResult;
import com.rymcu.forest.core.service.log.annotation.TransactionLogger;
-import com.rymcu.forest.entity.TransactionRecord;
import com.rymcu.forest.entity.User;
import com.rymcu.forest.enumerate.TransactionEnum;
import com.rymcu.forest.service.TransactionRecordService;
import com.rymcu.forest.util.UserUtils;
-import com.rymcu.forest.web.api.exception.BaseApiException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
@@ -15,11 +13,8 @@ import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;
diff --git a/src/main/java/com/rymcu/forest/core/service/log/VisitAspect.java b/src/main/java/com/rymcu/forest/core/service/log/VisitAspect.java
index e1c9c26..e7df59f 100644
--- a/src/main/java/com/rymcu/forest/core/service/log/VisitAspect.java
+++ b/src/main/java/com/rymcu/forest/core/service/log/VisitAspect.java
@@ -1,9 +1,9 @@
package com.rymcu.forest.core.service.log;
+import com.rymcu.forest.auth.JwtConstants;
import com.rymcu.forest.core.service.log.constant.LoggerConstant;
import com.rymcu.forest.dto.TokenUser;
import com.rymcu.forest.entity.Visit;
-import com.rymcu.forest.jwt.def.JwtConstants;
import com.rymcu.forest.service.ArticleService;
import com.rymcu.forest.service.VisitService;
import com.rymcu.forest.util.UserUtils;
diff --git a/src/main/java/com/rymcu/forest/core/service/security/AuthorshipAspect.java b/src/main/java/com/rymcu/forest/core/service/security/AuthorshipAspect.java
index a344aea..e4f6456 100644
--- a/src/main/java/com/rymcu/forest/core/service/security/AuthorshipAspect.java
+++ b/src/main/java/com/rymcu/forest/core/service/security/AuthorshipAspect.java
@@ -2,12 +2,12 @@ package com.rymcu.forest.core.service.security;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import com.rymcu.forest.auth.JwtConstants;
import com.rymcu.forest.core.service.security.annotation.AuthorshipInterceptor;
import com.rymcu.forest.dto.TokenUser;
import com.rymcu.forest.entity.Article;
import com.rymcu.forest.entity.Portfolio;
import com.rymcu.forest.enumerate.Module;
-import com.rymcu.forest.jwt.def.JwtConstants;
import com.rymcu.forest.mapper.UserMapper;
import com.rymcu.forest.service.ArticleService;
import com.rymcu.forest.service.PortfolioService;
@@ -76,7 +76,7 @@ public class AuthorshipAspect {
}
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
String idArticle;
- Long idAuthor = 0l;
+ Long idAuthor = 0L;
if (isAjax(request)) {
Object[] objects = joinPoint.getArgs();
JSONObject jsonObject;
diff --git a/src/main/java/com/rymcu/forest/core/service/security/SecurityAspect.java b/src/main/java/com/rymcu/forest/core/service/security/SecurityAspect.java
index 453d5eb..8a25025 100644
--- a/src/main/java/com/rymcu/forest/core/service/security/SecurityAspect.java
+++ b/src/main/java/com/rymcu/forest/core/service/security/SecurityAspect.java
@@ -2,8 +2,8 @@ package com.rymcu.forest.core.service.security;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import com.rymcu.forest.auth.JwtConstants;
import com.rymcu.forest.dto.TokenUser;
-import com.rymcu.forest.jwt.def.JwtConstants;
import com.rymcu.forest.util.UserUtils;
import com.rymcu.forest.web.api.exception.BaseApiException;
import com.rymcu.forest.web.api.exception.ErrorCode;
diff --git a/src/main/java/com/rymcu/forest/dto/SearchModel.java b/src/main/java/com/rymcu/forest/dto/SearchModel.java
deleted file mode 100644
index 5a44e51..0000000
--- a/src/main/java/com/rymcu/forest/dto/SearchModel.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.rymcu.forest.dto;
-
-import lombok.Data;
-
-/**
- * @author ronger
- */
-@Data
-public class SearchModel {
-
- private String label;
-
- private String value;
-
- private String type;
-
-}
diff --git a/src/main/java/com/rymcu/forest/dto/TokenUser.java b/src/main/java/com/rymcu/forest/dto/TokenUser.java
index 339e7bd..37ace1f 100644
--- a/src/main/java/com/rymcu/forest/dto/TokenUser.java
+++ b/src/main/java/com/rymcu/forest/dto/TokenUser.java
@@ -3,6 +3,8 @@ package com.rymcu.forest.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
+import java.util.Set;
+
/**
* @author ronger
*/
@@ -18,10 +20,10 @@ public class TokenUser {
private String token;
- private String avatarType;
-
private String avatarUrl;
- private Integer weights;
+ private String refreshToken;
+
+ private Set scope;
}
diff --git a/src/main/java/com/rymcu/forest/dto/UserInfoDTO.java b/src/main/java/com/rymcu/forest/dto/UserInfoDTO.java
index e41efee..0978d60 100644
--- a/src/main/java/com/rymcu/forest/dto/UserInfoDTO.java
+++ b/src/main/java/com/rymcu/forest/dto/UserInfoDTO.java
@@ -4,7 +4,6 @@ import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
-import javax.persistence.Column;
import java.io.Serializable;
import java.util.Date;
diff --git a/src/main/java/com/rymcu/forest/dto/baidu/TagNlpDTO.java b/src/main/java/com/rymcu/forest/dto/baidu/TagNlpDTO.java
deleted file mode 100644
index 14f156f..0000000
--- a/src/main/java/com/rymcu/forest/dto/baidu/TagNlpDTO.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.rymcu.forest.dto.baidu;
-
-import lombok.Data;
-
-import java.math.BigDecimal;
-
-/**
- * @author ronger
- */
-@Data
-public class TagNlpDTO {
-
- private BigDecimal score;
-
- private String tag;
-
-}
diff --git a/src/main/java/com/rymcu/forest/handler/AccountHandler.java b/src/main/java/com/rymcu/forest/handler/AccountHandler.java
index 96315a5..75f6dde 100644
--- a/src/main/java/com/rymcu/forest/handler/AccountHandler.java
+++ b/src/main/java/com/rymcu/forest/handler/AccountHandler.java
@@ -1,11 +1,14 @@
package com.rymcu.forest.handler;
import com.rymcu.forest.handler.event.AccountEvent;
+import com.rymcu.forest.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
+import javax.annotation.Resource;
+
/**
* Created on 2022/8/24 14:44.
*
@@ -17,10 +20,13 @@ import org.springframework.stereotype.Component;
@Component
public class AccountHandler {
+ @Resource
+ private UserMapper userMapper;
+
@Async
@EventListener
- public void processAccountLastLoginEvent(AccountEvent accountEvent) {
-
+ public void processAccountLastOnlineTimeEvent(AccountEvent accountEvent) {
+ userMapper.updateLastOnlineTimeByAccount(accountEvent.getAccount());
}
}
diff --git a/src/main/java/com/rymcu/forest/jwt/aop/RestAuthTokenInterceptor.java b/src/main/java/com/rymcu/forest/jwt/aop/RestAuthTokenInterceptor.java
deleted file mode 100644
index ba42544..0000000
--- a/src/main/java/com/rymcu/forest/jwt/aop/RestAuthTokenInterceptor.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.rymcu.forest.jwt.aop;
-
-
-import com.rymcu.forest.jwt.def.JwtConstants;
-import com.rymcu.forest.jwt.model.TokenModel;
-import com.rymcu.forest.jwt.service.TokenManager;
-import com.rymcu.forest.mapper.UserMapper;
-import com.rymcu.forest.web.api.exception.BaseApiException;
-import com.rymcu.forest.web.api.exception.ErrorCode;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureException;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.servlet.HandlerInterceptor;
-import org.springframework.web.servlet.ModelAndView;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.Objects;
-
-/**
- * Restful请求, Token校验规则拦截器(JWT)
- *
- * @author scott
- * @date 2015/7/30.
- */
-public class RestAuthTokenInterceptor implements HandlerInterceptor {
-
- @Autowired
- private TokenManager manager;
- @Resource
- private UserMapper userMapper;
-
- @Override
- public void afterCompletion(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse, Object obj, Exception exception) throws Exception {
- // TODO Auto-generated method stub
- }
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
- //从header中得到token
- String authHeader = request.getHeader(JwtConstants.AUTHORIZATION);
- if(StringUtils.isBlank(authHeader)){
- authHeader = request.getHeader(JwtConstants.UPLOAD_TOKEN);
- }
- if (StringUtils.isBlank(authHeader)) {
- throw new BaseApiException(ErrorCode.UNAUTHORIZED);
- }
- // 验证token
- Claims claims = null;
- try {
- claims = Jwts.parser().setSigningKey(JwtConstants.JWT_SECRET).parseClaimsJws(authHeader).getBody();
- }catch (final SignatureException e) {
- throw new BaseApiException(ErrorCode.INVALID_TOKEN);
- }
-
- Object username = claims.getId();
- if (Objects.isNull(username)) {
- throw new BaseApiException(ErrorCode.INVALID_TOKEN);
- }
- TokenModel model = manager.getToken(authHeader,username.toString());
- if (manager.checkToken(model)) {
- //如果token验证成功,将对象传递给下一个请求
- request.setAttribute(JwtConstants.CURRENT_TOKEN_CLAIMS, claims);
- //如果token验证成功,将token对应的用户id存在request中,便于之后注入
- request.setAttribute(JwtConstants.CURRENT_USER_NAME, model.getUsername());
- String uri = request.getRequestURI();
- // 判断是否为后台接口或财政划转接口
- String adminApi = "/admin/";
- String transactionApi = "/transaction/";
- if (uri.contains(adminApi) || uri.contains(transactionApi)) {
- // 判断管理员权限
- boolean hasPermission = userMapper.hasAdminPermission(model.getUsername());
- if (hasPermission) {
- return true;
- } else {
- throw new BaseApiException(ErrorCode.ACCESS_DENIED);
- }
- }
- return true;
- } else {
- throw new BaseApiException(ErrorCode.TOKEN_);
- }
- }
-
- @Override
- public void postHandle(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse, Object obj, ModelAndView modelandview) throws Exception {
- // TODO Auto-generated method stub
- }
-
-}
diff --git a/src/main/java/com/rymcu/forest/lucene/api/LuceneSearchController.java b/src/main/java/com/rymcu/forest/lucene/api/LuceneSearchController.java
index baebd86..2a0837b 100644
--- a/src/main/java/com/rymcu/forest/lucene/api/LuceneSearchController.java
+++ b/src/main/java/com/rymcu/forest/lucene/api/LuceneSearchController.java
@@ -17,8 +17,10 @@ import com.rymcu.forest.lucene.service.UserLuceneService;
import com.rymcu.forest.lucene.util.ArticleIndexUtil;
import com.rymcu.forest.lucene.util.PortfolioIndexUtil;
import com.rymcu.forest.lucene.util.UserIndexUtil;
-import com.rymcu.forest.util.Utils;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
diff --git a/src/main/java/com/rymcu/forest/lucene/lucene/PortfolioBeanIndex.java b/src/main/java/com/rymcu/forest/lucene/lucene/PortfolioBeanIndex.java
index 12de8cf..544bb74 100644
--- a/src/main/java/com/rymcu/forest/lucene/lucene/PortfolioBeanIndex.java
+++ b/src/main/java/com/rymcu/forest/lucene/lucene/PortfolioBeanIndex.java
@@ -1,7 +1,6 @@
package com.rymcu.forest.lucene.lucene;
import com.rymcu.forest.lucene.model.PortfolioLucene;
-import com.rymcu.forest.lucene.model.UserLucene;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
diff --git a/src/main/java/com/rymcu/forest/lucene/mapper/PortfolioLuceneMapper.java b/src/main/java/com/rymcu/forest/lucene/mapper/PortfolioLuceneMapper.java
index b75a7a4..c44ca01 100644
--- a/src/main/java/com/rymcu/forest/lucene/mapper/PortfolioLuceneMapper.java
+++ b/src/main/java/com/rymcu/forest/lucene/mapper/PortfolioLuceneMapper.java
@@ -1,10 +1,7 @@
package com.rymcu.forest.lucene.mapper;
import com.rymcu.forest.dto.PortfolioDTO;
-import com.rymcu.forest.dto.UserDTO;
-import com.rymcu.forest.entity.Portfolio;
import com.rymcu.forest.lucene.model.PortfolioLucene;
-import com.rymcu.forest.lucene.model.UserLucene;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
diff --git a/src/main/java/com/rymcu/forest/lucene/model/ArticleLucene.java b/src/main/java/com/rymcu/forest/lucene/model/ArticleLucene.java
index 125cb11..e870484 100644
--- a/src/main/java/com/rymcu/forest/lucene/model/ArticleLucene.java
+++ b/src/main/java/com/rymcu/forest/lucene/model/ArticleLucene.java
@@ -6,8 +6,6 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
-import javax.persistence.Id;
-
/**
* ArticleLucene
*
diff --git a/src/main/java/com/rymcu/forest/lucene/model/UserLucene.java b/src/main/java/com/rymcu/forest/lucene/model/UserLucene.java
index 708494a..e6d9e91 100644
--- a/src/main/java/com/rymcu/forest/lucene/model/UserLucene.java
+++ b/src/main/java/com/rymcu/forest/lucene/model/UserLucene.java
@@ -5,10 +5,6 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
-import org.apache.ibatis.type.JdbcType;
-import tk.mybatis.mapper.annotation.ColumnType;
-
-import javax.persistence.Column;
/**
* UserLucene
diff --git a/src/main/java/com/rymcu/forest/lucene/service/impl/UserLuceneServiceImpl.java b/src/main/java/com/rymcu/forest/lucene/service/impl/UserLuceneServiceImpl.java
index 78c8a9f..61212b3 100644
--- a/src/main/java/com/rymcu/forest/lucene/service/impl/UserLuceneServiceImpl.java
+++ b/src/main/java/com/rymcu/forest/lucene/service/impl/UserLuceneServiceImpl.java
@@ -1,14 +1,14 @@
package com.rymcu.forest.lucene.service.impl;
import com.rymcu.forest.dto.UserDTO;
-import com.rymcu.forest.lucene.lucene.UserBeanIndex;
import com.rymcu.forest.lucene.lucene.IKAnalyzer;
+import com.rymcu.forest.lucene.lucene.UserBeanIndex;
import com.rymcu.forest.lucene.mapper.UserLuceneMapper;
import com.rymcu.forest.lucene.model.UserLucene;
import com.rymcu.forest.lucene.service.UserLuceneService;
import com.rymcu.forest.lucene.util.LucenePath;
-import com.rymcu.forest.lucene.util.UserIndexUtil;
import com.rymcu.forest.lucene.util.SearchUtil;
+import com.rymcu.forest.lucene.util.UserIndexUtil;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
diff --git a/src/main/java/com/rymcu/forest/mapper/UserMapper.java b/src/main/java/com/rymcu/forest/mapper/UserMapper.java
index ce13898..d42c22e 100644
--- a/src/main/java/com/rymcu/forest/mapper/UserMapper.java
+++ b/src/main/java/com/rymcu/forest/mapper/UserMapper.java
@@ -20,7 +20,7 @@ public interface UserMapper extends Mapper {
* @param account
* @return
*/
- User findByAccount(@Param("account") String account);
+ User selectByAccount(@Param("account") String account);
/**
* 添加用户权限
@@ -147,10 +147,10 @@ public interface UserMapper extends Mapper {
/**
* 更新用户最后在线时间
- * @param email
+ * @param account
* @return
*/
- Integer updateLastOnlineTimeByEmail(@Param("email") String email);
+ Integer updateLastOnlineTimeByAccount(@Param("account") String account);
/**
* 判断用户是否拥有管理员权限
diff --git a/src/main/java/com/rymcu/forest/service/ArticleThumbsUpService.java b/src/main/java/com/rymcu/forest/service/ArticleThumbsUpService.java
index 8c71913..6185201 100644
--- a/src/main/java/com/rymcu/forest/service/ArticleThumbsUpService.java
+++ b/src/main/java/com/rymcu/forest/service/ArticleThumbsUpService.java
@@ -2,7 +2,6 @@ package com.rymcu.forest.service;
import com.rymcu.forest.core.service.Service;
import com.rymcu.forest.entity.ArticleThumbsUp;
-import com.rymcu.forest.web.api.exception.BaseApiException;
/**
* @author ronger
diff --git a/src/main/java/com/rymcu/forest/service/UserService.java b/src/main/java/com/rymcu/forest/service/UserService.java
index 9c74efb..a9e36bf 100644
--- a/src/main/java/com/rymcu/forest/service/UserService.java
+++ b/src/main/java/com/rymcu/forest/service/UserService.java
@@ -8,7 +8,7 @@ import com.rymcu.forest.entity.UserExtend;
import org.apache.ibatis.exceptions.TooManyResultsException;
import java.util.List;
-import java.util.Map;
+import java.util.Set;
/**
@@ -43,7 +43,7 @@ public interface UserService extends Service {
* @param password 密码
* @return Map
*/
- TokenUser login(String account, String password) throws ServiceException;
+ TokenUser login(String account, String password);
/**
* 通过 account 获取用户信息接口
@@ -169,10 +169,10 @@ public interface UserService extends Service {
/**
* 通过邮箱更新用户最后登录时间
*
- * @param email
+ * @param account
* @return
*/
- Integer updateLastOnlineTimeByEmail(String email);
+ Integer updateLastOnlineTimeByAccount(String account);
/**
* 查询用户扩展信息
@@ -181,4 +181,18 @@ public interface UserService extends Service {
* @return
*/
UserExtend findUserExtendInfo(Long idUser);
+
+ /**
+ * 刷新 token
+ * @param refreshToken
+ * @return
+ */
+ TokenUser refreshToken(String refreshToken);
+
+ /**
+ * 查询用户权限
+ * @param user
+ * @return
+ */
+ Set findUserPermissions(User user);
}
diff --git a/src/main/java/com/rymcu/forest/service/impl/SponsorServiceImpl.java b/src/main/java/com/rymcu/forest/service/impl/SponsorServiceImpl.java
index c9f2216..fce9036 100644
--- a/src/main/java/com/rymcu/forest/service/impl/SponsorServiceImpl.java
+++ b/src/main/java/com/rymcu/forest/service/impl/SponsorServiceImpl.java
@@ -7,14 +7,12 @@ import com.rymcu.forest.core.service.AbstractService;
import com.rymcu.forest.dto.ArticleDTO;
import com.rymcu.forest.entity.Sponsor;
import com.rymcu.forest.entity.TransactionRecord;
-import com.rymcu.forest.entity.User;
import com.rymcu.forest.enumerate.TransactionCode;
import com.rymcu.forest.enumerate.TransactionEnum;
import com.rymcu.forest.mapper.SponsorMapper;
import com.rymcu.forest.service.ArticleService;
import com.rymcu.forest.service.SponsorService;
import com.rymcu.forest.service.TransactionRecordService;
-import com.rymcu.forest.util.UserUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
diff --git a/src/main/java/com/rymcu/forest/service/impl/TagServiceImpl.java b/src/main/java/com/rymcu/forest/service/impl/TagServiceImpl.java
index ce37474..659fa0f 100644
--- a/src/main/java/com/rymcu/forest/service/impl/TagServiceImpl.java
+++ b/src/main/java/com/rymcu/forest/service/impl/TagServiceImpl.java
@@ -126,9 +126,6 @@ public class TagServiceImpl extends AbstractService implements TagService {
throw new BusinessException("标签 '" + tag.getTagTitle() + "' 已存在!");
}
}
- tag = new Tag();
- tag.setTagTitle(tag.getTagTitle());
- tag.setTagUri(tag.getTagUri());
if (StringUtils.isNotBlank(tag.getTagIconPath()) && tag.getTagIconPath().contains("base64")) {
String tagIconPath = UploadController.uploadBase64File(tag.getTagIconPath(), 2);
tag.setTagIconPath(tagIconPath);
diff --git a/src/main/java/com/rymcu/forest/service/impl/TopicServiceImpl.java b/src/main/java/com/rymcu/forest/service/impl/TopicServiceImpl.java
index d8e0746..c2b434d 100644
--- a/src/main/java/com/rymcu/forest/service/impl/TopicServiceImpl.java
+++ b/src/main/java/com/rymcu/forest/service/impl/TopicServiceImpl.java
@@ -1,7 +1,5 @@
package com.rymcu.forest.service.impl;
-import com.github.pagehelper.PageHelper;
-import com.github.pagehelper.PageInfo;
import com.rymcu.forest.core.exception.BusinessException;
import com.rymcu.forest.core.exception.ServiceException;
import com.rymcu.forest.core.service.AbstractService;
@@ -60,9 +58,6 @@ public class TopicServiceImpl extends AbstractService implements TopicSer
throw new BusinessException("专题 '" + topic.getTopicTitle() + "' 已存在!");
}
}
- topic = new Topic();
- topic.setTopicTitle(topic.getTopicTitle());
- topic.setTopicUri(topic.getTopicUri());
if (StringUtils.isNotBlank(topic.getTopicIconPath()) && topic.getTopicIconPath().contains("base64")) {
String topicIconPath = UploadController.uploadBase64File(topic.getTopicIconPath(), 3);
topic.setTopicIconPath(topicIconPath);
diff --git a/src/main/java/com/rymcu/forest/service/impl/TransactionRecordServiceImpl.java b/src/main/java/com/rymcu/forest/service/impl/TransactionRecordServiceImpl.java
index bc5c5d1..9992e41 100644
--- a/src/main/java/com/rymcu/forest/service/impl/TransactionRecordServiceImpl.java
+++ b/src/main/java/com/rymcu/forest/service/impl/TransactionRecordServiceImpl.java
@@ -13,7 +13,6 @@ import com.rymcu.forest.mapper.BankAccountMapper;
import com.rymcu.forest.mapper.TransactionRecordMapper;
import com.rymcu.forest.service.TransactionRecordService;
import com.rymcu.forest.util.DateUtil;
-import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
diff --git a/src/main/java/com/rymcu/forest/service/impl/UserServiceImpl.java b/src/main/java/com/rymcu/forest/service/impl/UserServiceImpl.java
index e6855cd..c68c2c0 100644
--- a/src/main/java/com/rymcu/forest/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/rymcu/forest/service/impl/UserServiceImpl.java
@@ -1,14 +1,14 @@
package com.rymcu.forest.service.impl;
+import com.github.f4b6a3.ulid.UlidCreator;
+import com.rymcu.forest.auth.JwtConstants;
+import com.rymcu.forest.auth.TokenManager;
import com.rymcu.forest.core.exception.*;
import com.rymcu.forest.core.service.AbstractService;
-import com.rymcu.forest.core.service.redis.RedisService;
import com.rymcu.forest.dto.*;
import com.rymcu.forest.entity.Role;
import com.rymcu.forest.entity.User;
import com.rymcu.forest.entity.UserExtend;
-import com.rymcu.forest.jwt.def.JwtConstants;
-import com.rymcu.forest.jwt.service.TokenManager;
import com.rymcu.forest.lucene.model.UserLucene;
import com.rymcu.forest.lucene.util.UserIndexUtil;
import com.rymcu.forest.mapper.RoleMapper;
@@ -16,18 +16,20 @@ import com.rymcu.forest.mapper.UserExtendMapper;
import com.rymcu.forest.mapper.UserMapper;
import com.rymcu.forest.service.LoginRecordService;
import com.rymcu.forest.service.UserService;
-import com.rymcu.forest.util.BeanCopierUtil;
import com.rymcu.forest.util.Utils;
import com.rymcu.forest.web.api.common.UploadController;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
+import java.util.concurrent.TimeUnit;
/**
@@ -40,8 +42,9 @@ public class UserServiceImpl extends AbstractService implements UserServic
private UserMapper userMapper;
@Resource
private RoleMapper roleMapper;
- @Resource
- private RedisService redisService;
+
+ @Autowired
+ private StringRedisTemplate redisTemplate;
@Resource
private TokenManager tokenManager;
@Resource
@@ -54,16 +57,16 @@ public class UserServiceImpl extends AbstractService implements UserServic
@Override
public User findByAccount(String account) throws TooManyResultsException {
- return userMapper.findByAccount(account);
+ return userMapper.selectByAccount(account);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean register(String email, String password, String code) {
- String vCode = redisService.get(email);
+ String vCode = redisTemplate.boundValueOps(email).get();
if (StringUtils.isNotBlank(vCode)) {
if (vCode.equals(code)) {
- User user = userMapper.findByAccount(email);
+ User user = userMapper.selectByAccount(email);
if (user != null) {
throw new AccountExistsException("该邮箱已被注册!");
} else {
@@ -77,7 +80,7 @@ public class UserServiceImpl extends AbstractService implements UserServic
user.setUpdatedTime(user.getCreatedTime());
user.setAvatarUrl(DEFAULT_AVATAR);
userMapper.insertSelective(user);
- user = userMapper.findByAccount(email);
+ user = userMapper.selectByAccount(email);
Role role = roleMapper.selectRoleByInputCode("user");
userMapper.insertUserRole(user.getIdUser(), role.getIdRole());
UserIndexUtil.addIndex(UserLucene.builder()
@@ -85,7 +88,7 @@ public class UserServiceImpl extends AbstractService implements UserServic
.nickname(user.getNickname())
.signature(user.getSignature())
.build());
- redisService.delete(email);
+ redisTemplate.delete(email);
return true;
}
}
@@ -115,17 +118,17 @@ public class UserServiceImpl extends AbstractService implements UserServic
@Override
public TokenUser login(String account, String password) {
- User user = userMapper.findByAccount(account);
+ User user = userMapper.selectByAccount(account);
if (user != null) {
if (Utils.comparePwd(password, user.getPassword())) {
userMapper.updateLastLoginTime(user.getIdUser());
- userMapper.updateLastOnlineTimeByEmail(user.getEmail());
+ userMapper.updateLastOnlineTimeByAccount(user.getAccount());
TokenUser tokenUser = new TokenUser();
- BeanCopierUtil.copy(user, tokenUser);
- tokenUser.setToken(tokenManager.createToken(user.getEmail()));
- tokenUser.setWeights(userMapper.selectRoleWeightsByUser(user.getIdUser()));
+ tokenUser.setToken(tokenManager.createToken(user.getAccount()));
+ tokenUser.setRefreshToken(UlidCreator.getUlid().toString());
+ redisTemplate.boundValueOps(tokenUser.getRefreshToken()).set(account, JwtConstants.REFRESH_TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
// 保存登录日志
- loginRecordService.saveLoginRecord(tokenUser.getIdUser());
+ loginRecordService.saveLoginRecord(user.getIdUser());
return tokenUser;
} else {
throw new AuthenticationException("密码错误");
@@ -142,7 +145,7 @@ public class UserServiceImpl extends AbstractService implements UserServic
@Override
public boolean forgetPassword(String code, String password) throws ServiceException {
- String email = redisService.get(code);
+ String email = redisTemplate.boundValueOps(code).get();
if (StringUtils.isBlank(email)) {
throw new ServiceException("链接已失效");
} else {
@@ -250,7 +253,7 @@ public class UserServiceImpl extends AbstractService implements UserServic
Long idUser = changeEmailDTO.getIdUser();
String email = changeEmailDTO.getEmail();
String code = changeEmailDTO.getCode();
- String vCode = redisService.get(email);
+ String vCode = redisTemplate.boundValueOps(email).get();
if (StringUtils.isNotBlank(vCode) && StringUtils.isNotBlank(code) && vCode.equals(code)) {
int result = userMapper.updateEmail(idUser, email);
if (result == 0) {
@@ -272,13 +275,13 @@ public class UserServiceImpl extends AbstractService implements UserServic
public List findUsers(UserSearchDTO searchDTO) {
List users = userMapper.selectUsers(searchDTO);
users.forEach(user -> {
- user.setOnlineStatus(getUserOnlineStatus(user.getEmail()));
+ user.setOnlineStatus(getUserOnlineStatus(user.getAccount()));
});
return users;
}
- private Integer getUserOnlineStatus(String email) {
- String lastOnlineTime = redisService.get(JwtConstants.LAST_ONLINE + email);
+ private Integer getUserOnlineStatus(String account) {
+ String lastOnlineTime = redisTemplate.boundValueOps(JwtConstants.LAST_ONLINE + account).get();
if (StringUtils.isBlank(lastOnlineTime)) {
return 0;
}
@@ -286,8 +289,8 @@ public class UserServiceImpl extends AbstractService implements UserServic
}
@Override
- public Integer updateLastOnlineTimeByEmail(String email) {
- return userMapper.updateLastOnlineTimeByEmail(email);
+ public Integer updateLastOnlineTimeByAccount(String account) {
+ return userMapper.updateLastOnlineTimeByAccount(account);
}
@Override
@@ -300,4 +303,36 @@ public class UserServiceImpl extends AbstractService implements UserServic
}
return userExtend;
}
+
+ @Override
+ public TokenUser refreshToken(String refreshToken) {
+ String account = redisTemplate.boundValueOps(refreshToken).get();
+ if (StringUtils.isNotBlank(account)) {
+ User nucleicUser = userMapper.selectByAccount(account);
+ if (nucleicUser != null) {
+ TokenUser tokenUser = new TokenUser();
+ tokenUser.setToken(tokenManager.createToken(nucleicUser.getAccount()));
+ tokenUser.setRefreshToken(UlidCreator.getUlid().toString());
+ redisTemplate.boundValueOps(tokenUser.getRefreshToken()).set(account, JwtConstants.REFRESH_TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
+ redisTemplate.delete(refreshToken);
+ return tokenUser;
+ } else {
+ throw new UnknownAccountException("未知账号");
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Set findUserPermissions(User user) {
+ Set permissions = new HashSet<>();
+ List roles = roleMapper.selectRoleByIdUser(user.getIdUser());
+ for (Role role : roles) {
+ if (StringUtils.isNotBlank(role.getInputCode())) {
+ permissions.add(role.getInputCode());
+ }
+ }
+ permissions.add("user");
+ return permissions;
+ }
}
diff --git a/src/main/java/com/rymcu/forest/task/BaiDuCronTask.java b/src/main/java/com/rymcu/forest/task/BaiDuCronTask.java
index 6872773..9c43f2d 100644
--- a/src/main/java/com/rymcu/forest/task/BaiDuCronTask.java
+++ b/src/main/java/com/rymcu/forest/task/BaiDuCronTask.java
@@ -5,7 +5,6 @@ import com.rymcu.forest.util.BaiDuUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
/**
* @author ronger
diff --git a/src/main/java/com/rymcu/forest/util/UserUtils.java b/src/main/java/com/rymcu/forest/util/UserUtils.java
index c69b70e..9655bcf 100644
--- a/src/main/java/com/rymcu/forest/util/UserUtils.java
+++ b/src/main/java/com/rymcu/forest/util/UserUtils.java
@@ -1,17 +1,16 @@
package com.rymcu.forest.util;
+import com.rymcu.forest.auth.JwtConstants;
+import com.rymcu.forest.auth.TokenManager;
+import com.rymcu.forest.auth.TokenModel;
import com.rymcu.forest.dto.TokenUser;
import com.rymcu.forest.entity.User;
-import com.rymcu.forest.jwt.def.JwtConstants;
-import com.rymcu.forest.jwt.model.TokenModel;
-import com.rymcu.forest.jwt.service.TokenManager;
import com.rymcu.forest.mapper.UserMapper;
-import com.rymcu.forest.web.api.exception.BaseApiException;
-import com.rymcu.forest.web.api.exception.ErrorCode;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.authz.UnauthorizedException;
import java.util.Objects;
@@ -28,7 +27,7 @@ public class UserUtils {
*
* @return
*/
- public static User getCurrentUserByToken() throws BaseApiException {
+ public static User getCurrentUserByToken() {
String authHeader = ContextHolderUtils.getRequest().getHeader(JwtConstants.AUTHORIZATION);
if (authHeader == null) {
return null;
@@ -38,16 +37,16 @@ public class UserUtils {
try {
claims = Jwts.parser().setSigningKey(JwtConstants.JWT_SECRET).parseClaimsJws(authHeader).getBody();
} catch (final SignatureException e) {
- throw new BaseApiException(ErrorCode.UNAUTHORIZED);
+ throw new UnauthorizedException();
}
Object account = claims.getId();
if (StringUtils.isNotBlank(Objects.toString(account, ""))) {
TokenModel model = tokenManager.getToken(authHeader, account.toString());
if (tokenManager.checkToken(model)) {
- return userMapper.findByAccount(account.toString());
+ return userMapper.selectByAccount(account.toString());
}
} else {
- throw new BaseApiException(ErrorCode.UNAUTHORIZED);
+ throw new UnauthorizedException();
}
return null;
}
@@ -65,13 +64,12 @@ public class UserUtils {
if (StringUtils.isNotBlank(Objects.toString(account, ""))) {
TokenModel model = tokenManager.getToken(token, account.toString());
if (tokenManager.checkToken(model)) {
- User user = userMapper.findByAccount(account.toString());
+ User user = userMapper.selectByAccount(account.toString());
if (user != null) {
TokenUser tokenUser = new TokenUser();
BeanCopierUtil.copy(user, tokenUser);
tokenUser.setAccount(user.getEmail());
tokenUser.setToken(token);
- tokenUser.setWeights(userMapper.selectRoleWeightsByUser(user.getIdUser()));
return tokenUser;
}
}
diff --git a/src/main/java/com/rymcu/forest/web/api/admin/AdminArticleController.java b/src/main/java/com/rymcu/forest/web/api/admin/AdminArticleController.java
index 9b2cac8..c94b02b 100644
--- a/src/main/java/com/rymcu/forest/web/api/admin/AdminArticleController.java
+++ b/src/main/java/com/rymcu/forest/web/api/admin/AdminArticleController.java
@@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
-import java.util.Map;
/**
* Created on 2022/1/3 10:11.
diff --git a/src/main/java/com/rymcu/forest/web/api/admin/AdminCurrencyRuleController.java b/src/main/java/com/rymcu/forest/web/api/admin/AdminCurrencyRuleController.java
index 39cf31a..b59d2d3 100644
--- a/src/main/java/com/rymcu/forest/web/api/admin/AdminCurrencyRuleController.java
+++ b/src/main/java/com/rymcu/forest/web/api/admin/AdminCurrencyRuleController.java
@@ -7,7 +7,6 @@ import com.rymcu.forest.core.result.GlobalResultGenerator;
import com.rymcu.forest.dto.TransactionRecordDTO;
import com.rymcu.forest.entity.CurrencyRule;
import com.rymcu.forest.service.CurrencyRuleService;
-import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@@ -15,9 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* Created on 2022/3/6 18:26.
diff --git a/src/main/java/com/rymcu/forest/web/api/admin/DashboardController.java b/src/main/java/com/rymcu/forest/web/api/admin/DashboardController.java
index 6b17356..530aec7 100644
--- a/src/main/java/com/rymcu/forest/web/api/admin/DashboardController.java
+++ b/src/main/java/com/rymcu/forest/web/api/admin/DashboardController.java
@@ -9,14 +9,12 @@ import com.rymcu.forest.dto.BankAccountDTO;
import com.rymcu.forest.dto.UserInfoDTO;
import com.rymcu.forest.dto.admin.Dashboard;
import com.rymcu.forest.service.DashboardService;
-import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
diff --git a/src/main/java/com/rymcu/forest/web/api/auth/AuthController.java b/src/main/java/com/rymcu/forest/web/api/auth/AuthController.java
new file mode 100644
index 0000000..40bc1ad
--- /dev/null
+++ b/src/main/java/com/rymcu/forest/web/api/auth/AuthController.java
@@ -0,0 +1,61 @@
+package com.rymcu.forest.web.api.auth;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.rymcu.forest.auth.TokenManager;
+import com.rymcu.forest.core.result.GlobalResult;
+import com.rymcu.forest.core.result.GlobalResultGenerator;
+import com.rymcu.forest.dto.TokenUser;
+import com.rymcu.forest.entity.User;
+import com.rymcu.forest.service.UserService;
+import com.rymcu.forest.util.BeanCopierUtil;
+import com.rymcu.forest.util.UserUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+
+/**
+ * @author ronger
+ */
+@RestController
+@RequestMapping("/api/v1/auth")
+public class AuthController {
+
+ @Resource
+ private UserService userService;
+ @Resource
+ TokenManager tokenManager;
+
+ @PostMapping("/login")
+ public GlobalResult login(@RequestBody User user) {
+ TokenUser tokenUser = userService.login(user.getAccount(), user.getPassword());
+ return GlobalResultGenerator.genSuccessResult(tokenUser);
+ }
+
+ @PostMapping("/refresh-token")
+ public GlobalResult refreshToken(@RequestBody TokenUser tokenUser) {
+ tokenUser = userService.refreshToken(tokenUser.getRefreshToken());
+ return GlobalResultGenerator.genSuccessResult(tokenUser);
+ }
+
+ @PostMapping("/logout")
+ public GlobalResult logout() {
+ User user = UserUtils.getCurrentUserByToken();
+ if (Objects.nonNull(user)) {
+ tokenManager.deleteToken(user.getAccount());
+ }
+ return GlobalResultGenerator.genSuccessResult();
+ }
+
+ @GetMapping("/user")
+ public GlobalResult user() {
+ User user = UserUtils.getCurrentUserByToken();
+ TokenUser tokenUser = new TokenUser();
+ BeanCopierUtil.copy(user, tokenUser);
+ tokenUser.setScope(userService.findUserPermissions(user));
+ JSONObject object = new JSONObject();
+ object.put("user", tokenUser);
+ return GlobalResultGenerator.genSuccessResult(object);
+ }
+
+}
diff --git a/src/main/java/com/rymcu/forest/web/api/bank/BankAccountController.java b/src/main/java/com/rymcu/forest/web/api/bank/BankAccountController.java
index 2e1db18..50062f9 100644
--- a/src/main/java/com/rymcu/forest/web/api/bank/BankAccountController.java
+++ b/src/main/java/com/rymcu/forest/web/api/bank/BankAccountController.java
@@ -8,14 +8,11 @@ import com.rymcu.forest.dto.BankAccountDTO;
import com.rymcu.forest.dto.BankAccountSearchDTO;
import com.rymcu.forest.dto.TransactionRecordDTO;
import com.rymcu.forest.service.BankAccountService;
-import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* @author ronger
diff --git a/src/main/java/com/rymcu/forest/web/api/bank/BankController.java b/src/main/java/com/rymcu/forest/web/api/bank/BankController.java
index e157a08..d2cf8e0 100644
--- a/src/main/java/com/rymcu/forest/web/api/bank/BankController.java
+++ b/src/main/java/com/rymcu/forest/web/api/bank/BankController.java
@@ -4,20 +4,15 @@ import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rymcu.forest.core.result.GlobalResult;
import com.rymcu.forest.core.result.GlobalResultGenerator;
-import com.rymcu.forest.dto.ArticleDTO;
import com.rymcu.forest.dto.BankDTO;
-import com.rymcu.forest.entity.Bank;
import com.rymcu.forest.service.BankService;
-import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* @author ronger
diff --git a/src/main/java/com/rymcu/forest/web/api/bank/WalletController.java b/src/main/java/com/rymcu/forest/web/api/bank/WalletController.java
index e9ea1ac..0f2994c 100644
--- a/src/main/java/com/rymcu/forest/web/api/bank/WalletController.java
+++ b/src/main/java/com/rymcu/forest/web/api/bank/WalletController.java
@@ -7,15 +7,15 @@ import com.rymcu.forest.core.result.GlobalResultGenerator;
import com.rymcu.forest.core.service.security.annotation.SecurityInterceptor;
import com.rymcu.forest.dto.BankAccountDTO;
import com.rymcu.forest.dto.TransactionRecordDTO;
+import com.rymcu.forest.entity.User;
import com.rymcu.forest.service.BankAccountService;
-import com.rymcu.forest.util.Utils;
+import com.rymcu.forest.util.UserUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
+import java.util.Objects;
/**
* Created on 2021/12/10 19:25.
@@ -31,20 +31,22 @@ public class WalletController {
private BankAccountService bankAccountService;
- @GetMapping("/{idUser}")
- @SecurityInterceptor
- public GlobalResult detail(@PathVariable Long idUser) {
- BankAccountDTO bankAccount = bankAccountService.findBankAccountByIdUser(idUser);
+ @GetMapping("/detail")
+ public GlobalResult detail() {
+ User user = UserUtils.getCurrentUserByToken();
+ BankAccountDTO bankAccount = bankAccountService.findBankAccountByIdUser(user.getIdUser());
return GlobalResultGenerator.genSuccessResult(bankAccount);
}
@GetMapping("/transaction-records")
- @SecurityInterceptor
public GlobalResult> transactionRecords(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "20") Integer rows, HttpServletRequest request) {
- String idUser = request.getParameter("idUser");
+ User user = UserUtils.getCurrentUserByToken();
String startDate = request.getParameter("startDate");
String endDate = request.getParameter("endDate");
- BankAccountDTO bankAccount = bankAccountService.findBankAccountByIdUser(Long.valueOf(idUser));
+ BankAccountDTO bankAccount = bankAccountService.findBankAccountByIdUser(user.getIdUser());
+ if (Objects.isNull(bankAccount)) {
+ return GlobalResultGenerator.genSuccessResult(new PageInfo<>());
+ }
PageHelper.startPage(page, rows);
List list = bankAccountService.findUserTransactionRecords(bankAccount.getBankAccount(), startDate, endDate);
PageInfo pageInfo = new PageInfo(list);
diff --git a/src/main/java/com/rymcu/forest/web/api/common/UploadController.java b/src/main/java/com/rymcu/forest/web/api/common/UploadController.java
index 788eb28..b397821 100644
--- a/src/main/java/com/rymcu/forest/web/api/common/UploadController.java
+++ b/src/main/java/com/rymcu/forest/web/api/common/UploadController.java
@@ -1,10 +1,10 @@
package com.rymcu.forest.web.api.common;
+import com.rymcu.forest.auth.JwtConstants;
import com.rymcu.forest.core.result.GlobalResult;
import com.rymcu.forest.core.result.GlobalResultGenerator;
import com.rymcu.forest.dto.LinkToImageUrlDTO;
import com.rymcu.forest.dto.TokenUser;
-import com.rymcu.forest.jwt.def.JwtConstants;
import com.rymcu.forest.service.ForestFileService;
import com.rymcu.forest.util.FileUtils;
import com.rymcu.forest.util.SpringContextHolder;
diff --git a/src/main/java/com/rymcu/forest/web/api/notification/NotificationController.java b/src/main/java/com/rymcu/forest/web/api/notification/NotificationController.java
index 4508ecc..d4333f4 100644
--- a/src/main/java/com/rymcu/forest/web/api/notification/NotificationController.java
+++ b/src/main/java/com/rymcu/forest/web/api/notification/NotificationController.java
@@ -9,14 +9,12 @@ import com.rymcu.forest.entity.Notification;
import com.rymcu.forest.entity.User;
import com.rymcu.forest.service.NotificationService;
import com.rymcu.forest.util.UserUtils;
-import com.rymcu.forest.util.Utils;
import com.rymcu.forest.web.api.exception.BaseApiException;
import com.rymcu.forest.web.api.exception.ErrorCode;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
/**
diff --git a/src/main/java/com/rymcu/forest/web/api/portfolio/PortfolioController.java b/src/main/java/com/rymcu/forest/web/api/portfolio/PortfolioController.java
index 81a8e99..2c5b208 100644
--- a/src/main/java/com/rymcu/forest/web/api/portfolio/PortfolioController.java
+++ b/src/main/java/com/rymcu/forest/web/api/portfolio/PortfolioController.java
@@ -17,8 +17,6 @@ import com.rymcu.forest.web.api.exception.BaseApiException;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.Map;
/**
* @author ronger
diff --git a/src/main/java/com/rymcu/forest/web/api/tag/TagController.java b/src/main/java/com/rymcu/forest/web/api/tag/TagController.java
index 9b4556a..32260fe 100644
--- a/src/main/java/com/rymcu/forest/web/api/tag/TagController.java
+++ b/src/main/java/com/rymcu/forest/web/api/tag/TagController.java
@@ -8,12 +8,10 @@ import com.rymcu.forest.dto.ArticleDTO;
import com.rymcu.forest.dto.LabelModel;
import com.rymcu.forest.service.ArticleService;
import com.rymcu.forest.service.TagService;
-import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
-import java.util.Map;
/**
* @author ronger
diff --git a/src/main/java/com/rymcu/forest/web/api/topic/TopicController.java b/src/main/java/com/rymcu/forest/web/api/topic/TopicController.java
index d90d1f9..41365b9 100644
--- a/src/main/java/com/rymcu/forest/web/api/topic/TopicController.java
+++ b/src/main/java/com/rymcu/forest/web/api/topic/TopicController.java
@@ -9,12 +9,10 @@ import com.rymcu.forest.dto.ArticleDTO;
import com.rymcu.forest.entity.Topic;
import com.rymcu.forest.service.ArticleService;
import com.rymcu.forest.service.TopicService;
-import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
-import java.util.Map;
/**
* @author ronger
diff --git a/src/main/java/com/rymcu/forest/web/api/user/UserController.java b/src/main/java/com/rymcu/forest/web/api/user/UserController.java
index 7e7d06f..01756f1 100644
--- a/src/main/java/com/rymcu/forest/web/api/user/UserController.java
+++ b/src/main/java/com/rymcu/forest/web/api/user/UserController.java
@@ -13,13 +13,10 @@ import com.rymcu.forest.service.ArticleService;
import com.rymcu.forest.service.FollowService;
import com.rymcu.forest.service.PortfolioService;
import com.rymcu.forest.service.UserService;
-import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* @author ronger
diff --git a/src/main/java/com/rymcu/forest/web/api/user/UserInfoController.java b/src/main/java/com/rymcu/forest/web/api/user/UserInfoController.java
index 46db78f..70603b1 100644
--- a/src/main/java/com/rymcu/forest/web/api/user/UserInfoController.java
+++ b/src/main/java/com/rymcu/forest/web/api/user/UserInfoController.java
@@ -13,13 +13,10 @@ import com.rymcu.forest.entity.LoginRecord;
import com.rymcu.forest.entity.UserExtend;
import com.rymcu.forest.service.LoginRecordService;
import com.rymcu.forest.service.UserService;
-import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* @author ronger
diff --git a/src/main/java/mapper/SearchMapper.xml b/src/main/java/mapper/SearchMapper.xml
deleted file mode 100644
index 7bdfcb4..0000000
--- a/src/main/java/mapper/SearchMapper.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/mapper/UserMapper.xml b/src/main/java/mapper/UserMapper.xml
index f2c6cef..c666d3f 100644
--- a/src/main/java/mapper/UserMapper.xml
+++ b/src/main/java/mapper/UserMapper.xml
@@ -78,11 +78,11 @@
update forest_user set password = #{password} where id = #{idUser}
-
- update forest_user set last_online_time = sysdate() where email = #{email}
+
+ update forest_user set last_online_time = sysdate() where account = #{account}
-