Răsfoiți Sursa

测试前端使用微信code直接登录功能

klzhangweiya 3 ani în urmă
părinte
comite
b2232c7c3c

+ 1 - 1
fbs_code/fbs-backend/fbs-security-common/src/main/java/com/yyjc/fbs/constant/ConstantKey.java

@@ -34,5 +34,5 @@ public interface ConstantKey {
 	String IMAGE_CODE = "cems_image_code";
 
 	int LOGIN_FAILED_COUNT_REFRESH_MILLSEC = 30 * 60 * 1000;
-	String[] NOFILTERURI = { "/login", "/error" };
+	String[] NOFILTERURI = { "/login", "/error","/users/wxlogin" };
 }

+ 83 - 0
fbs_code/fbs-backend/fbs-security-common/src/main/java/com/yyjc/fbs/util/MyHttpUtils.java

@@ -0,0 +1,83 @@
+package com.yyjc.fbs.util;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * @author Lenovo
+ * @description MyHttpUtils
+ * @date 2023/3/31 18:25
+ */
+public class MyHttpUtils {
+
+    public static String sendGet(String url) throws Exception {
+        URL obj = new URL(url);
+        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+
+        // optional default is GET
+        con.setRequestMethod("GET");
+
+        int responseCode = con.getResponseCode();
+        System.out.println("\nSending 'GET' request to URL : " + url);
+        System.out.println("Response Code : " + responseCode);
+
+        BufferedReader in = new BufferedReader(
+                new InputStreamReader(con.getInputStream()));
+        String inputLine;
+        StringBuffer response = new StringBuffer();
+
+        while ((inputLine = in.readLine()) != null) {
+            response.append(inputLine);
+        }
+        in.close();
+
+        // return result
+        return response.toString();
+    }
+
+    public static String sendPost(String url, String urlParameters, String requestHeaders) throws Exception {
+        URL obj = new URL(url);
+        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+
+        //add request header
+        con.setRequestMethod("POST");
+        con.setRequestProperty("User-Agent", "Mozilla/5.0");
+        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
+        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+        con.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
+        con.setRequestProperty("requestHeaders", requestHeaders);
+
+        // Send post request
+        con.setDoOutput(true);
+        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
+        wr.writeBytes(urlParameters);
+        wr.flush();
+        wr.close();
+
+        int responseCode = con.getResponseCode();
+        System.out.println("\nSending 'POST' request to URL : " + url);
+        System.out.println("Post parameters : " + urlParameters);
+        System.out.println("Response Code : " + responseCode);
+
+        BufferedReader in = new BufferedReader(
+                new InputStreamReader(con.getInputStream()));
+        String inputLine;
+        StringBuffer response = new StringBuffer();
+
+        while ((inputLine = in.readLine()) != null) {
+            response.append(inputLine);
+        }
+        in.close();
+
+        // return result
+        return response.toString();
+    }
+
+
+
+}

+ 40 - 0
fbs_code/fbs-backend/fbs-security-common/src/main/java/com/yyjc/fbs/vo/WxLoginInfo.java

@@ -0,0 +1,40 @@
+package com.yyjc.fbs.vo;
+
+/**
+ * @author Lenovo
+ * @description WxLoginInfo
+ * @date 2023/4/2 19:11
+ */
+public class WxLoginInfo {
+    private String wxcode;
+
+    public WxLoginInfo() {
+    }
+
+    public WxLoginInfo(String wxcode, String openid) {
+        this.wxcode = wxcode;
+        this.openid = openid;
+    }
+
+    public WxLoginInfo(String wxcode) {
+        this.wxcode = wxcode;
+    }
+
+    public String getOpenid() {
+        return openid;
+    }
+
+    public void setOpenid(String openid) {
+        this.openid = openid;
+    }
+
+    private String openid;
+
+    public String getWxcode() {
+        return wxcode;
+    }
+
+    public void setWxcode(String wxcode) {
+        this.wxcode = wxcode;
+    }
+}

+ 64 - 0
fbs_code/fbs-backend/fbs-security-service/src/main/java/com/yyjc/fbs/bean/UserExt.java

@@ -0,0 +1,64 @@
+package com.yyjc.fbs.bean;
+
+/**
+ * @author Lenovo
+ * @description UserExt
+ * @date 2023/4/3 9:47
+ */
+public class UserExt {
+    private Integer id;
+    private Integer userid;
+    private String wx_open_id;
+    private Long insert_time;
+    private Long update_time;
+
+    public UserExt() {
+    }
+
+    public UserExt(Integer userid, String wx_open_id, Long insert_time, Long update_time) {
+        this.userid = userid;
+        this.wx_open_id = wx_open_id;
+        this.insert_time = insert_time;
+        this.update_time = update_time;
+    }
+
+    public Long getUpdate_time() {
+        return update_time;
+    }
+
+    public void setUpdate_time(Long update_time) {
+        this.update_time = update_time;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getUserid() {
+        return userid;
+    }
+
+    public void setUserid(Integer userid) {
+        this.userid = userid;
+    }
+
+    public String getWx_open_id() {
+        return wx_open_id;
+    }
+
+    public void setWx_open_id(String wx_open_id) {
+        this.wx_open_id = wx_open_id;
+    }
+
+    public Long getInsert_time() {
+        return insert_time;
+    }
+
+    public void setInsert_time(Long insert_time) {
+        this.insert_time = insert_time;
+    }
+}

+ 16 - 0
fbs_code/fbs-backend/fbs-security-service/src/main/java/com/yyjc/fbs/bean/mapper/UserMapper.java

@@ -2,6 +2,7 @@ package com.yyjc.fbs.bean.mapper;
 
 import java.util.List;
 
+import com.yyjc.fbs.bean.UserExt;
 import com.yyjc.fbs.bean.mapper.provider.UserMapperProvider;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Insert;
@@ -76,4 +77,19 @@ public interface UserMapper {
     @Select("select * from user where id = #{userId}")
     User findUserById(Integer userId);
 
+    @Select("select * from user_ext where wx_open_id = #{openId} or userid = #{userId} order by UPDATE_TIME desc LIMIT 1")
+    UserExt findUserExtByWxOpenId(@Param("openId")String openId,@Param("userId") Integer userId);
+
+    @Insert("INSERT INTO user_ext( USERID , wx_open_id ,INSERT_TIME,UPDATE_TIME   ) VALUES ( #{userExt.userid} , " +
+            "#{userExt" +
+            ".wx_open_id} , #{userExt.insert_time}, #{userExt.update_time} )")
+    int insertUserExt(@Param("userExt") UserExt userExt);
+
+    @Delete("delete from user_ext where userid = #{userId}")
+    public int delUserExtByUserId(Integer userId);
+
+    @Update("UPDATE user_ext SET wx_open_id = #{userExt.wx_open_id},UPDATE_TIME = #{userExt.update_time} WHERE " +
+            "(ID=#{userExt.id})")
+    int updateUserWxOpenId(@Param("userExt") UserExt userExt);
+
 }

+ 9 - 2
fbs_code/fbs-backend/fbs-security-service/src/main/java/com/yyjc/fbs/config/WebSecurityConfig.java

@@ -12,6 +12,7 @@ import com.yyjc.fbs.config.jwt.JWTLoginFilter;
 import com.yyjc.fbs.service.ICompanyBiz;
 import com.yyjc.fbs.service.IUserLoginLogsBiz;
 import com.yyjc.fbs.service.UserService;
+import com.yyjc.fbs.service.biz.UserToolService;
 import com.yyjc.fbs.vo.Result;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -40,7 +41,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 
 @Configuration
 @EnableGlobalMethodSecurity(prePostEnabled = true)
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 	@Value("${login.imageCodeFlag:true}")
 	boolean imagecodeFlag;
 	@Autowired
@@ -57,6 +58,11 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 	private ICompanyBiz iCompanyBiz;
 	@Autowired
 	private IUserLoginLogsBiz iUserLoginLogsBiz;
+	@Autowired
+	private WechatAppConfig wechatAppConfig;
+
+	@Autowired
+	private UserToolService userToolService;
 
 	@Override
 	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
@@ -120,7 +126,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 					}
 				}).and().logout().permitAll().and().csrf().disable().exceptionHandling()
 				.accessDeniedHandler(authenticationDeniedHandler).and()
-				.addFilter(new JWTLoginFilter(authenticationManager(), imagecodeFlag, iCompanyBiz, iUserLoginLogsBiz))
+				.addFilter(new JWTLoginFilter(authenticationManager(), imagecodeFlag, iCompanyBiz, iUserLoginLogsBiz,
+						wechatAppConfig,userToolService))
 				// 验证token
 				.addFilter(new JWTAuthenticationFilter(authenticationManager()));
 	}

+ 36 - 0
fbs_code/fbs-backend/fbs-security-service/src/main/java/com/yyjc/fbs/config/WechatAppConfig.java

@@ -0,0 +1,36 @@
+package com.yyjc.fbs.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Lenovo
+ * @description WechatAppConfig
+ * @date 2023/3/31 16:41
+ */
+@Component
+@ConfigurationProperties(prefix = "wechat")
+public class WechatAppConfig {
+
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public String getAppSecret() {
+        return appSecret;
+    }
+
+    public void setAppSecret(String appSecret) {
+        this.appSecret = appSecret;
+    }
+
+    private String appId;
+
+    private String appSecret;
+}

+ 27 - 1
fbs_code/fbs-backend/fbs-security-service/src/main/java/com/yyjc/fbs/config/jwt/JWTLoginFilter.java

@@ -4,6 +4,8 @@ import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collection;
@@ -15,12 +17,16 @@ import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.yyjc.fbs.bean.UserExt;
+import com.yyjc.fbs.config.WechatAppConfig;
 import com.yyjc.fbs.service.ICompanyBiz;
 import com.yyjc.fbs.service.IUserLoginLogsBiz;
+import com.yyjc.fbs.service.biz.UserToolService;
 import com.yyjc.fbs.vo.Result;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
@@ -48,18 +54,24 @@ import io.jsonwebtoken.SignatureAlgorithm;
 
 public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter {
 
+	private final UserToolService userToolService;
 	private AuthenticationManager authenticationManager;
 	private static final Logger log = LoggerFactory.getLogger(JWTLoginFilter.class);
 	private boolean imageCodeFlag;
 	private ICompanyBiz iCompanyBiz;
 	private IUserLoginLogsBiz iUserLoginLogsBiz;
+	private WechatAppConfig wechatAppConfig;
+
+
 
 	public JWTLoginFilter(AuthenticationManager authenticationManager, boolean imageCodeFlag, ICompanyBiz iCompanyBiz,
-			IUserLoginLogsBiz iUserLoginLogsBiz) {
+			IUserLoginLogsBiz iUserLoginLogsBiz,WechatAppConfig wechatAppConfig,UserToolService userToolService) {
 		this.authenticationManager = authenticationManager;
 		this.imageCodeFlag = imageCodeFlag;
 		this.iCompanyBiz = iCompanyBiz;
 		this.iUserLoginLogsBiz = iUserLoginLogsBiz;
+		this.wechatAppConfig = wechatAppConfig;
+		this.userToolService = userToolService;
 	}
 
 	// 接收并解析用户凭证
@@ -120,6 +132,20 @@ public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter {
 			response.setContentType("application/json;charset=UTF-8");
 			
 			LoginResult result = getResult(auth.getName(), token, user);
+
+			//-----如果前端参数带有wxcode,说明用户需要保存openId  start-----
+			String wxCode = request.getParameter("wxcode");
+			if(StringUtils.isNotBlank(wxCode)){
+				String wxOpenId = userToolService.getWxOpenId(wxCode);
+				if(StringUtils.isNotBlank(wxOpenId)){
+					LocalDateTime now = LocalDateTime.now();
+					DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+					UserExt userExt = new UserExt( user.getId(),wxOpenId,Long.parseLong(dtf.format(now)),
+							Long.parseLong(dtf.format(now)));
+					userToolService.AddOrUpdateUserExt(userExt);
+				}
+			}
+			//-----如果前端参数带有wxcode,说明用户需要保存openId  end-----
 			response.getWriter().print(JSON.toJSONString(new Result<LoginResult>(0, "登陆成功", result)));
 		} catch (Exception e) {
 			e.printStackTrace();

+ 2 - 0
fbs_code/fbs-backend/fbs-security-service/src/main/java/com/yyjc/fbs/service/UserService.java

@@ -23,4 +23,6 @@ public class UserService implements UserDetailsService {
 		user.setRoles(userMapper.findRole(user.getId()));
 		return user;
 	}
+
+
 }

+ 4 - 0
fbs_code/fbs-backend/fbs-security-service/src/main/java/com/yyjc/fbs/service/biz/BasicService.java

@@ -1,5 +1,6 @@
 package com.yyjc.fbs.service.biz;
 
+import com.yyjc.fbs.bean.UserExt;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import com.yyjc.fbs.bean.mapper.BridgeMapper;
@@ -20,4 +21,7 @@ public class BasicService {
 	@Autowired
 	protected MenuMapper menuMapper;
 
+
+
+
 }

+ 123 - 12
fbs_code/fbs-backend/fbs-security-service/src/main/java/com/yyjc/fbs/service/biz/UserToolService.java

@@ -1,29 +1,42 @@
 package com.yyjc.fbs.service.biz;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.yyjc.fbs.bean.*;
+import com.yyjc.fbs.config.UserPassInfoAuthenticationToken;
+import com.yyjc.fbs.config.WechatAppConfig;
+import com.yyjc.fbs.constant.ConstantKey;
+import com.yyjc.fbs.service.ICompanyBiz;
+import com.yyjc.fbs.util.MyHttpUtils;
+import com.yyjc.fbs.vo.*;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.stereotype.Service;
-import com.yyjc.fbs.bean.Company;
-import com.yyjc.fbs.bean.Org;
-import com.yyjc.fbs.bean.User;
-import com.yyjc.fbs.bean.UserTypeEnum;
 import com.yyjc.fbs.bean.mapper.CompanyMapper;
-import com.yyjc.fbs.vo.LoginUser;
-import com.yyjc.fbs.vo.Role;
-import com.yyjc.fbs.vo.UserCondition;
-import com.yyjc.fbs.vo.UserOfRole;
 import com.github.pagehelper.PageHelper;
 
 @Service
 public class UserToolService extends BasicService {
+	@Autowired
+	private UserDetailsService userDetailsService;
 
 	@Autowired
 	private CompanyMapper companyMapper;
 
+	@Autowired
+	private ICompanyBiz iCompanyBiz;
+
+	@Autowired
+	private WechatAppConfig wechatAppConfig;
+
 	public boolean registerUser(LoginUser user) {
 		this.userMapper.saveUser(user);
 		return true;
@@ -156,4 +169,102 @@ public class UserToolService extends BasicService {
 		});
 		return users;
 	}
+
+
+	/***
+	 * 根据openId获取用户信息
+	 * @param openId
+	 * @return
+	 */
+	public User findUserExtByWxOpenId(String openId) {
+		UserExt userExt = userMapper.findUserExtByWxOpenId(openId,0);
+		if (userExt != null) {
+			User user = findUserById(userExt.getUserid());
+			return user;
+		}
+		return null;
+	}
+
+	/***
+	 * 更新用户扩展表信息
+	 * @param input
+	 * @return
+	 */
+	public boolean AddOrUpdateUserExt(UserExt input) {
+		UserExt userExt = userMapper.findUserExtByWxOpenId("",input.getUserid());
+		if (userExt != null) {
+			input.setId(userExt.getId());
+			userMapper.updateUserWxOpenId(userExt);
+		}else{
+			userMapper.insertUserExt(input);
+		}
+		return true;
+	}
+
+	/***
+	 * 微信的code登录
+	 * @param user
+	 * @return
+	 */
+	public LoginResult LoginByWxCode(User user,WxLoginInfo wxLoginInfo) {
+		UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername());
+		if (userDetails == null) {
+			return null;
+		}
+		Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
+		LoginInfo info = new LoginInfo();
+		info.setLogin_name(userDetails.getUsername());
+		// 定义存放角色集合的对象
+		for (GrantedAuthority grantedAuthority : authorities) {
+			info.getRoles().add(grantedAuthority.getAuthority());
+		}
+		// 设置过期时间
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(new Date());
+		calendar.add(Calendar.DAY_OF_MONTH, 30);
+		Date time = calendar.getTime();
+		info.setUser_detail(user);
+		String token = Jwts.builder().setSubject(JSONObject.toJSONString(info)).setExpiration(time)
+				.signWith(SignatureAlgorithm.HS512, ConstantKey.SIGNING_KEY) // 设置算法
+				.compact();
+		LoginResult result = getResult(user.getUsername(), token, user,wxLoginInfo);
+		return result;
+	}
+	private LoginResult getResult(String loginName, String token, BasicUser user,WxLoginInfo wxLoginInfo) {
+		LoginResult result = new LoginResult();
+		result.setAuthName(loginName);
+		result.setAuth(ConstantKey.JWT_PREFIX + token);
+		result.setUserType(user.getUser_type());
+		result.setEnterpriseId(user.getEnterprise_id());
+		result.setWxLoginInfo(wxLoginInfo);
+		if (UserTypeEnum.company.getType() == user.getUser_type()) {
+			Company com = iCompanyBiz.selectByid(Integer.valueOf(user.getEnterprise_id()));
+			if (null != com) {
+				result.setLoginMsg(com.getName());
+			}
+		} else {
+			Org org = iCompanyBiz.selectOrgById(Integer.valueOf(user.getEnterprise_id()));
+			if (null != org && StringUtils.isNotBlank(org.getDescription())) {
+				result.setLoginMsg(org.getDescription());
+			} else {
+				result.setLoginMsg("餐饮油烟在线监控系统");
+			}
+		}
+		return result;
+	}
+
+
+	public  String getWxOpenId(String wxCode) throws Exception {
+		String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code" +
+				"=%s&grant_type" +
+				"=authorization_code",wechatAppConfig.getAppId(),wechatAppConfig.getAppSecret(),wxCode);
+		String res = MyHttpUtils.sendGet(url);
+		Object parse = JSONObject.parse(res);
+		String openId = "";
+		if (parse instanceof JSONObject) {
+			JSONObject jsonObject = (JSONObject) parse;
+			openId= jsonObject.getString("openid");
+		}
+		return openId;
+	}
 }