he2802 4 lat temu
rodzic
commit
3969c41689

+ 10 - 34
zhongzheng-api/src/main/java/com/zhongzheng/controller/wx/WxLoginController.java

@@ -11,7 +11,10 @@ import com.zhongzheng.common.utils.ServletUtils;
 import com.zhongzheng.framework.web.service.SysLoginService;
 import com.zhongzheng.framework.web.service.SysPermissionService;
 import com.zhongzheng.framework.web.service.TokenService;
+import com.zhongzheng.framework.web.service.WxTokenService;
 import com.zhongzheng.modules.system.service.ISysMenuService;
+import com.zhongzheng.modules.user.entity.ClientLoginUser;
+import com.zhongzheng.modules.user.service.IUserService;
 import com.zhongzheng.modules.wx.bo.WxLoginBody;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -32,17 +35,10 @@ import java.util.Set;
 public class WxLoginController
 {
     @Autowired
-    private SysLoginService loginService;
+    private IUserService iUserService;
 
     @Autowired
-    private ISysMenuService menuService;
-
-    @Autowired
-    private SysPermissionService permissionService;
-
-    @Autowired
-    private TokenService tokenService;
-
+    private WxTokenService wxTokenService;
     /**
      * 登录方法
      *
@@ -54,7 +50,9 @@ public class WxLoginController
     public AjaxResult login(@RequestBody WxLoginBody loginBody)
     {
         AjaxResult ajax = AjaxResult.success();
-
+        String union = "cba";
+        String token = iUserService.login(union);
+        ajax.put(Constants.TOKEN, token);
         return ajax;
     }
 
@@ -67,32 +65,10 @@ public class WxLoginController
     @GetMapping("getInfo")
     public AjaxResult getInfo()
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        SysUser user = loginUser.getUser();
-        // 角色集合
-        Set<String> roles = permissionService.getRolePermission(user);
-        // 权限集合
-        Set<String> permissions = permissionService.getMenuPermission(user);
+        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
         Map<String,Object> map = new HashMap<>();
-        map.put("user", user);
-        map.put("roles", roles);
-        map.put("permissions", permissions);
+        map.put("union_id", loginUser.getUser().getUnionId());
         return AjaxResult.success(map);
     }
 
-    /**
-     * 获取路由信息
-     *
-     * @return 路由信息
-     */
-    @ApiOperation("路由菜单信息")
-    @GetMapping("getRouters")
-    public AjaxResult getRouters()
-    {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        // 用户信息
-        SysUser user = loginUser.getUser();
-        List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId());
-        return AjaxResult.success(menuService.buildMenus(menus));
-    }
 }

+ 14 - 2
zhongzheng-api/src/main/java/com/zhongzheng/core/config/SwaggerConfig.java

@@ -8,8 +8,10 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
 import springfox.documentation.builders.PathSelectors;
 import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
 import springfox.documentation.service.*;
 import springfox.documentation.spi.DocumentationType;
 import springfox.documentation.spi.service.contexts.SecurityContext;
@@ -62,9 +64,10 @@ public class SwaggerConfig
                 .paths(PathSelectors.any())
                 .build()
                 /* 设置安全模式,swagger可以设置访问token */
-                .securitySchemes(securitySchemes())
+            //    .securitySchemes(securitySchemes())
                 .securityContexts(securityContexts())
-                .pathMapping(pathMapping);
+                .pathMapping(pathMapping)
+                .globalOperationParameters(getGlobalOperationParameters());
     }
 
     /**
@@ -121,4 +124,13 @@ public class SwaggerConfig
                 .version("版本号:" + ruoyiConfig.getVersion())
                 .build();
     }
+
+    private List<Parameter> getGlobalOperationParameters() {
+        List<Parameter> pars = new ArrayList<>();
+        ParameterBuilder parameterBuilder = new ParameterBuilder();
+        // header query cookie
+        parameterBuilder.name("X-Auth-Token").description("token").modelRef(new ModelRef("string")).parameterType("header").defaultValue("test").required(false);
+        pars.add(parameterBuilder.build());
+        return pars;
+    }
 }

+ 10 - 1
zhongzheng-common/src/main/java/com/zhongzheng/common/constant/Constants.java

@@ -2,7 +2,7 @@ package com.zhongzheng.common.constant;
 
 /**
  * 通用常量信息
- * 
+ *
  * @author zhongzheng
  */
 public class Constants
@@ -62,6 +62,8 @@ public class Constants
      */
     public static final String LOGIN_TOKEN_KEY = "login_tokens:";
 
+    public static final String WX_LOGIN_TOKEN_KEY = "wx_login_tokens:";
+
     /**
      * 防重提交 redis key
      */
@@ -82,11 +84,18 @@ public class Constants
      */
     public static final String TOKEN_PREFIX = "Bearer ";
 
+    /**
+     * 微信令牌前缀
+     */
+    public static final String WX_TOKEN_PREFIX = "WX ";
+
     /**
      * 令牌前缀
      */
     public static final String LOGIN_USER_KEY = "login_user_key";
 
+    public static final String WX_LOGIN_USER_KEY = "wx_login_user_key";
+
     /**
      * 用户ID
      */

+ 24 - 8
zhongzheng-framework/src/main/java/com/zhongzheng/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -1,9 +1,12 @@
 package com.zhongzheng.framework.security.filter;
 
 import cn.hutool.core.lang.Validator;
+import com.zhongzheng.modules.user.entity.ClientLoginUser;
 import com.zhongzheng.common.core.domain.model.LoginUser;
 import com.zhongzheng.common.utils.SecurityUtils;
 import com.zhongzheng.framework.web.service.TokenService;
+import com.zhongzheng.framework.web.service.WxTokenService;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -19,7 +22,7 @@ import java.io.IOException;
 
 /**
  * token过滤器 验证token有效性
- * 
+ *
  * @author zhongzheng
  */
 @Component
@@ -28,17 +31,30 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
     @Autowired
     private TokenService tokenService;
 
+    @Autowired
+    private WxTokenService wxTokenService;
+
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
             throws ServletException, IOException
     {
-        LoginUser loginUser = tokenService.getLoginUser(request);
-        if (Validator.isNotNull(loginUser) && Validator.isNull(SecurityUtils.getAuthentication()))
-        {
-            tokenService.verifyToken(loginUser);
-            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
-            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+        String wxToken = wxTokenService.getToken(request);
+        if(StringUtils.isNoneEmpty(wxToken)){
+            ClientLoginUser clientLoginUser = wxTokenService.getLoginUser(request);
+            if(clientLoginUser!=null){
+                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(clientLoginUser, null,null);
+                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+            }
+        }else{
+            LoginUser loginUser = tokenService.getLoginUser(request);
+            if (Validator.isNotNull(loginUser) && Validator.isNull(SecurityUtils.getAuthentication()))
+            {
+                tokenService.verifyToken(loginUser);
+                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
+                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+            }
         }
         chain.doFilter(request, response);
     }

+ 1 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/TokenService.java

@@ -71,6 +71,7 @@ public class TokenService
      */
     public LoginUser getLoginUser(HttpServletRequest request)
     {
+
         //测试用户
         String test_token = request.getHeader("X-Auth-Token");
         if("test".equals(test_token)){

+ 35 - 7
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/impl/UserServiceImpl.java → zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/UserServiceImpl.java

@@ -1,23 +1,26 @@
-package com.zhongzheng.modules.user.service.impl;
+package com.zhongzheng.framework.web.service;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
-import com.zhongzheng.common.utils.DateUtils;
-import org.springframework.stereotype.Service;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
+import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.modules.user.bo.UserAddBo;
-import com.zhongzheng.modules.user.bo.UserQueryBo;
 import com.zhongzheng.modules.user.bo.UserEditBo;
+import com.zhongzheng.modules.user.bo.UserQueryBo;
 import com.zhongzheng.modules.user.domain.User;
+import com.zhongzheng.modules.user.entity.ClientLoginUser;
 import com.zhongzheng.modules.user.mapper.UserMapper;
-import com.zhongzheng.modules.user.vo.UserVo;
 import com.zhongzheng.modules.user.service.IUserService;
+import com.zhongzheng.modules.user.vo.UserVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -30,12 +33,37 @@ import java.util.stream.Collectors;
 @Service
 public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
 
+    @Autowired
+    private WxTokenService wxTokenService;
+
     @Override
     public UserVo queryById(Long userId){
         User db = this.baseMapper.selectById(userId);
         return BeanUtil.toBean(db, UserVo.class);
     }
 
+    @Override
+    public User queryByUnionId(String unionId) {
+        User user = getOne(new LambdaQueryWrapper<User>()
+                .eq(User::getUnionId,unionId)
+                .last("limit 1"));
+        if (Validator.isNotNull(user)) {
+            return user;
+        }
+        return null;
+    }
+
+    @Override
+    public String login(String unionId) {
+        User user = queryByUnionId(unionId);
+        if(user==null){
+            throw new CustomException("unionId不存在");
+        }
+        ClientLoginUser loginUser = new ClientLoginUser();
+        loginUser.setUser(user);
+        return wxTokenService.createToken(loginUser);
+    }
+
     @Override
     public List<UserVo> queryList(UserQueryBo bo) {
         LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();

+ 231 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/WxTokenService.java

@@ -0,0 +1,231 @@
+package com.zhongzheng.framework.web.service;
+
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import com.zhongzheng.common.constant.Constants;
+import com.zhongzheng.modules.user.entity.ClientLoginUser;
+import com.zhongzheng.common.core.redis.RedisCache;
+import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.common.utils.ip.AddressUtils;
+import com.zhongzheng.common.utils.ip.IpUtils;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * token验证处理
+ *
+ * @author zhongzheng
+ */
+@Component
+public class WxTokenService
+{
+    // 令牌自定义标识
+    @Value("${token.header}")
+    private String header;
+
+    // 令牌秘钥
+    @Value("${token.secret}")
+    private String secret;
+
+    // 令牌有效期(默认30分钟)
+    @Value("${token.expireTime}")
+    private int expireTime;
+
+    protected static final long MILLIS_SECOND = 1000;
+
+    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
+
+    private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Resource
+    private AuthenticationManager authenticationManager;
+
+    /**
+     * 获取用户身份信息
+     *
+     * @return 用户信息
+     */
+    public ClientLoginUser getLoginUser(HttpServletRequest request)
+    {
+        // 获取请求携带的令牌
+        String token = getToken(request);
+        if (Validator.isNotEmpty(token))
+        {
+            Claims claims = parseToken(token);
+            // 解析对应的权限以及用户信息
+            String uuid = (String) claims.get(Constants.WX_LOGIN_USER_KEY);
+            String userKey = getTokenKey(uuid);
+            ClientLoginUser user = redisCache.getCacheObject(userKey);
+            return user;
+        }
+        return null;
+    }
+
+
+
+    /**
+     * 设置用户身份信息
+     */
+    public void setLoginUser(ClientLoginUser loginUser)
+    {
+        if (Validator.isNotNull(loginUser) && Validator.isNotEmpty(loginUser.getToken()))
+        {
+            refreshToken(loginUser);
+        }
+    }
+
+    /**
+     * 删除用户身份信息
+     */
+    public void delLoginUser(String token)
+    {
+        if (Validator.isNotEmpty(token))
+        {
+            String userKey = getTokenKey(token);
+            redisCache.deleteObject(userKey);
+        }
+    }
+
+    /**
+     * 创建令牌
+     *
+     * @param loginUser 用户信息
+     * @return 令牌
+     */
+    public String createToken(ClientLoginUser loginUser)
+    {
+        String token = IdUtil.fastUUID();
+        loginUser.setToken(token);
+        setUserAgent(loginUser);
+        refreshToken(loginUser);
+
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(Constants.WX_LOGIN_USER_KEY, token);
+        return createToken(claims);
+    }
+
+    /**
+     * 验证令牌有效期,相差不足20分钟,自动刷新缓存
+     *
+     * @param loginUser
+     * @return 令牌
+     */
+    public void verifyToken(ClientLoginUser loginUser)
+    {
+        long expireTime = loginUser.getExpireTime();
+        long currentTime = System.currentTimeMillis();
+        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
+        {
+            refreshToken(loginUser);
+        }
+    }
+
+    /**
+     * 刷新令牌有效期
+     *
+     * @param loginUser 登录信息
+     */
+    public void refreshToken(ClientLoginUser loginUser)
+    {
+        loginUser.setLoginTime(System.currentTimeMillis());
+        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
+        // 根据uuid将loginUser缓存
+        String userKey = getTokenKey(loginUser.getToken());
+        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
+    }
+
+    /**
+     * 设置用户代理信息
+     *
+     * @param loginUser 登录信息
+     */
+    public void setUserAgent(ClientLoginUser loginUser)
+    {
+        UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
+        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
+        loginUser.setIpaddr(ip);
+        loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
+        loginUser.setBrowser(userAgent.getBrowser().getName());
+        loginUser.setOs(userAgent.getOs().getName());
+    }
+
+    /**
+     * 从数据声明生成令牌
+     *
+     * @param claims 数据声明
+     * @return 令牌
+     */
+    private String createToken(Map<String, Object> claims)
+    {
+        String token = Jwts.builder()
+                .setClaims(claims)
+                .signWith(SignatureAlgorithm.HS512, secret).compact();
+        return token;
+    }
+
+    /**
+     * 从令牌中获取数据声明
+     *
+     * @param token 令牌
+     * @return 数据声明
+     */
+    private Claims parseToken(String token)
+    {
+        return Jwts.parser()
+                .setSigningKey(secret)
+                .parseClaimsJws(token)
+                .getBody();
+    }
+
+    /**
+     * 从令牌中获取用户名
+     *
+     * @param token 令牌
+     * @return 用户名
+     */
+    public String getUsernameFromToken(String token)
+    {
+        Claims claims = parseToken(token);
+        return claims.getSubject();
+    }
+
+    /**
+     * 获取请求token
+     *
+     * @param request
+     * @return token
+     */
+    public String getToken(HttpServletRequest request)
+    {
+        String token = request.getHeader(header);
+        if (Validator.isNotEmpty(token) && token.startsWith(Constants.WX_TOKEN_PREFIX))
+        {
+            token = token.replace(Constants.WX_TOKEN_PREFIX, "");
+            return token;
+        }else{
+            return null;
+        }
+
+    }
+
+    private String getTokenKey(String uuid)
+    {
+        return Constants.WX_LOGIN_TOKEN_KEY + uuid;
+    }
+}

+ 1 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/domain/User.java

@@ -99,4 +99,5 @@ private static final long serialVersionUID=1L;
     /** 状态 1正常 0关闭 */
     private Integer status;
 
+    private String unionId;
 }

+ 71 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/entity/ClientLoginUser.java

@@ -0,0 +1,71 @@
+package com.zhongzheng.modules.user.entity;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.zhongzheng.modules.user.domain.User;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * 登录用户身份权限
+ *
+ * @author zhongzheng
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class ClientLoginUser
+{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户唯一标识
+     */
+    private String token;
+
+    /**
+     * 登录时间
+     */
+    private Long loginTime;
+
+    /**
+     * 过期时间
+     */
+    private Long expireTime;
+
+    /**
+     * 登录IP地址
+     */
+    private String ipaddr;
+
+    /**
+     * 登录地点
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+
+
+    /**
+     * 用户信息
+     */
+    private User user;
+
+
+
+}

+ 5 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/IUserService.java

@@ -23,6 +23,11 @@ public interface IUserService extends IService<User> {
 	 */
 	UserVo queryById(Long userId);
 
+
+	User queryByUnionId(String unionId);
+
+	String login(String unionId);
+
 	/**
 	 * 查询列表
 	 */

+ 1 - 0
zhongzheng-system/src/main/resources/mapper/modules/user/UserMapper.xml

@@ -29,6 +29,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="createTime" column="create_time"/>
         <result property="updateTime" column="update_time"/>
         <result property="status" column="status"/>
+        <result property="unionId" column="union_id"/>
     </resultMap>