From f468d57607abe004bc11bf22b895c2fa496f6802 Mon Sep 17 00:00:00 2001 From: D <3066417822@qq.com> Date: Tue, 16 Jan 2024 02:09:33 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9B=86=E6=88=90=E5=BE=AE=E4=BF=A1=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E7=99=BB=E5=BD=95=E5=92=8C=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/微信登录.drawio | 76 +++++ pom.xml | 24 +- ruoyi-admin/pom.xml | 11 +- .../main/resources/application-mybatis.yml | 14 + .../main/resources/application-thirdAuth.yml | 12 + .../src/main/resources/application.yml | 17 +- ruoyi-third-auth/pom.xml | 35 ++ .../ruoyi/third/constant/WxH5Constant.java | 52 +++ .../third/constant/WxMiniAppConstant.java | 52 +++ .../third/controller/WxLoginService.java | 40 +++ .../service/Impl/WxLoginServiceImpl.java | 65 ++++ .../ruoyi/third/service/WxLoginService.java | 7 + .../com/ruoyi/third/utils/HttpClientUtil.java | 298 ++++++++++++++++++ 13 files changed, 671 insertions(+), 32 deletions(-) create mode 100644 doc/微信登录.drawio create mode 100644 ruoyi-admin/src/main/resources/application-mybatis.yml create mode 100644 ruoyi-admin/src/main/resources/application-thirdAuth.yml create mode 100644 ruoyi-third-auth/pom.xml create mode 100644 ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxH5Constant.java create mode 100644 ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxMiniAppConstant.java create mode 100644 ruoyi-third-auth/src/main/java/com/ruoyi/third/controller/WxLoginService.java create mode 100644 ruoyi-third-auth/src/main/java/com/ruoyi/third/service/Impl/WxLoginServiceImpl.java create mode 100644 ruoyi-third-auth/src/main/java/com/ruoyi/third/service/WxLoginService.java create mode 100644 ruoyi-third-auth/src/main/java/com/ruoyi/third/utils/HttpClientUtil.java diff --git a/doc/微信登录.drawio b/doc/微信登录.drawio new file mode 100644 index 0000000..509b195 --- /dev/null +++ b/doc/微信登录.drawio @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5705ea0..c2dbe85 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,7 @@ ${mybatis-plus-boot-starter.version} + javax.xml.bind jaxb-api @@ -115,19 +116,6 @@ ${oshi.version} - - - io.springfox - springfox-boot-starter - ${swagger.version} - - - io.swagger - swagger-models - - - - commons-io @@ -212,6 +200,13 @@ ${ruoyi.version} + + + com.ruoyi + ruoyi-third-auth + ${ruoyi.version} + + jakarta.servlet jakarta.servlet-api @@ -235,6 +230,7 @@ ruoyi-quartz ruoyi-generator ruoyi-common + ruoyi-third-auth pom @@ -284,4 +280,4 @@ - + \ No newline at end of file diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 433ef13..a4cfab7 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -1,6 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> ruoyi com.ruoyi @@ -52,6 +53,12 @@ com.ruoyi ruoyi-generator + + + + com.ruoyi + ruoyi-third-auth + @@ -81,4 +88,4 @@ ${project.artifactId} - + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-mybatis.yml b/ruoyi-admin/src/main/resources/application-mybatis.yml new file mode 100644 index 0000000..7c78430 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-mybatis.yml @@ -0,0 +1,14 @@ +# MyBatis Plus配置 +mybatis-plus: + # 搜索指定包别名 + typeAliasesPackage: com.ruoyi.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-thirdAuth.yml b/ruoyi-admin/src/main/resources/application-thirdAuth.yml new file mode 100644 index 0000000..6fad0e4 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-thirdAuth.yml @@ -0,0 +1,12 @@ +# 请输入自己的appid和appsecret +wx: + miniapp: + open: true + appId: miniAppid + appSecret: miniAppSercret + url: https://api.weixin.qq.com/sns/jscode2session + h5: + open: true + appId: h5AppId + appSecret: h5Secret + url: https://api.weixin.qq.com/sns/oauth2/access_token \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index c623ff5..9a8fff9 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -55,7 +55,7 @@ spring: # 国际化资源文件路径 basename: i18n/messages profiles: - active: druid + active: druid,mybatis,thirdAuth # 文件上传 servlet: multipart: @@ -101,21 +101,6 @@ token: # 令牌有效期(默认30分钟) expireTime: 30 -# MyBatis Plus配置 -mybatis-plus: - # 搜索指定包别名 - typeAliasesPackage: com.ruoyi.**.domain - # 配置mapper的扫描,找到所有的mapper.xml映射文件 - mapperLocations: classpath*:mapper/**/*Mapper.xml - # 加载全局的配置文件 - configLocation: classpath:mybatis/mybatis-config.xml - -# PageHelper分页插件 -pagehelper: - helperDialect: mysql - supportMethodsArguments: true - params: count=countSql - # Swagger配置 swagger: # 是否开启swagger diff --git a/ruoyi-third-auth/pom.xml b/ruoyi-third-auth/pom.xml new file mode 100644 index 0000000..0a75e29 --- /dev/null +++ b/ruoyi-third-auth/pom.xml @@ -0,0 +1,35 @@ + + + + ruoyi + com.ruoyi + 3.8.7.3.1 + + 4.0.0 + + ruoyi-third-auth + + + system系统模块 + + + + + + + com.ruoyi + ruoyi-common + + + + + org.apache.httpcomponents + httpclient + 4.5.2 + + + + + \ No newline at end of file diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxH5Constant.java b/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxH5Constant.java new file mode 100644 index 0000000..150cefe --- /dev/null +++ b/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxH5Constant.java @@ -0,0 +1,52 @@ +package com.ruoyi.third.constant; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class WxH5Constant { + @Value("${wx.h5.appId}") + private String appId; + + @Value("${wx.h5.appSecret}") + private String appSecret; + + @Value("${wx.h5.url}") + private String url; + + @Value("${wx.h5.open}") + private Boolean open; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + 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; + } + + public Boolean getOpen() { + return open; + } + + public void setOpen(Boolean open) { + this.open = open; + } + +} diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxMiniAppConstant.java b/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxMiniAppConstant.java new file mode 100644 index 0000000..b00ff85 --- /dev/null +++ b/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxMiniAppConstant.java @@ -0,0 +1,52 @@ +package com.ruoyi.third.constant; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class WxMiniAppConstant { + @Value("${wx.miniapp.appId}") + private String appId; + + @Value("${wx.miniapp.appSecret}") + private String appSecret; + + @Value("${wx.miniapp.url}") + private String url; + + @Value("${wx.miniapp.open}") + private Boolean open; + + public Boolean getOpen() { + return open; + } + + public void setOpen(Boolean open) { + this.open = open; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + 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; + } + +} diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/controller/WxLoginService.java b/ruoyi-third-auth/src/main/java/com/ruoyi/third/controller/WxLoginService.java new file mode 100644 index 0000000..f167adf --- /dev/null +++ b/ruoyi-third-auth/src/main/java/com/ruoyi/third/controller/WxLoginService.java @@ -0,0 +1,40 @@ +package com.ruoyi.third.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.third.constant.WxH5Constant; +import com.ruoyi.third.constant.WxMiniAppConstant; +import com.ruoyi.third.service.Impl.WxLoginServiceImpl;; + +@RestController +@RequestMapping("/wx") +public class WxLoginService extends BaseController { + @Autowired + public WxH5Constant wxH5AppConstant; + + @Autowired + public WxMiniAppConstant wxMiniAppConstant; + + @Autowired + WxLoginServiceImpl wxLoginServiceImpl; + + @Anonymous + @GetMapping("/miniapp/{code}") + public AjaxResult loginMiniApp(@PathVariable("code") String code) { + return success(wxLoginServiceImpl.doLoginMiniApp(code)); + } + + @Anonymous + @GetMapping("/h5/{code}") + public AjaxResult loginH5App(@PathVariable("code") String code) { + return success(wxLoginServiceImpl.doLoginMiniApp(code)); + } + +} diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/Impl/WxLoginServiceImpl.java b/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/Impl/WxLoginServiceImpl.java new file mode 100644 index 0000000..4c560c9 --- /dev/null +++ b/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/Impl/WxLoginServiceImpl.java @@ -0,0 +1,65 @@ +package com.ruoyi.third.service.Impl; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.third.constant.WxH5Constant; +import com.ruoyi.third.constant.WxMiniAppConstant; +import com.ruoyi.third.service.WxLoginService; +import com.ruoyi.third.utils.HttpClientUtil; + +@Service +public class WxLoginServiceImpl implements WxLoginService { + @Autowired + private WxMiniAppConstant wxAppConstant; + + @Autowired + private WxH5Constant wxH5Constant; + + @Autowired + private HttpClientUtil httpClientUtil; + + public Map doLogin(String url, String appid, String secret, String code) { + String getMessageUrl = url + "?appid=" + appid + "&secret=" + secret + "&js_code=" + code + + "&grant_type=authorization_code"; + String result = httpClientUtil.sendHttpGet(getMessageUrl); + JSONObject jsonObject = JSON.parseObject(result); + if (jsonObject.containsKey("openid")) { + String openid = jsonObject.getString("openid"); + String sessionKey = jsonObject.getString("session_key"); + return new HashMap() { + { + put("openid", openid); + put("sessionKey", sessionKey); + } + }; + } else { + throw new ServiceException(jsonObject.getString("errmsg"), jsonObject.getIntValue("errcode")); + } + } + + @Override + public String doLoginH5(String code) { + return doLogin( + wxH5Constant.getUrl(), + wxH5Constant.getAppId(), + wxH5Constant.getAppSecret(), + code).get("openid"); + } + + @Override + public String doLoginMiniApp(String code) { + return doLogin( + wxAppConstant.getUrl(), + wxAppConstant.getAppId(), + wxAppConstant.getAppSecret(), + code).get("openid"); + } + +} diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/WxLoginService.java b/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/WxLoginService.java new file mode 100644 index 0000000..244a143 --- /dev/null +++ b/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/WxLoginService.java @@ -0,0 +1,7 @@ +package com.ruoyi.third.service; + +public interface WxLoginService { + public String doLoginMiniApp(String code); + + public String doLoginH5(String code); +} diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/utils/HttpClientUtil.java b/ruoyi-third-auth/src/main/java/com/ruoyi/third/utils/HttpClientUtil.java new file mode 100644 index 0000000..62ba0eb --- /dev/null +++ b/ruoyi-third-auth/src/main/java/com/ruoyi/third/utils/HttpClientUtil.java @@ -0,0 +1,298 @@ +package com.ruoyi.third.utils; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.apache.http.conn.util.PublicSuffixMatcher; +import org.apache.http.conn.util.PublicSuffixMatcherLoader; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.springframework.stereotype.Component; + + +@Component +public class HttpClientUtil { + + /** + * 默认参数设置 + * setConnectTimeout:设置连接超时时间,单位毫秒。 + * setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。 + * setSocketTimeout:请求获取数据的超时时间,单位毫秒。访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。 暂时定义15分钟 + */ + private RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(600000).setConnectTimeout(600000).setConnectionRequestTimeout(600000).build(); + + /** + * 静态内部类---作用:单例产生类的实例 + * + * @author Administrator + */ + private static class LazyHolder { + private static final HttpClientUtil INSTANCE = new HttpClientUtil(); + + } + + private HttpClientUtil() { + } + + public static HttpClientUtil getInstance() { + return LazyHolder.INSTANCE; + } + + /** + * 发送 post请求 + * + * @param httpUrl 地址 + */ + public String sendHttpPost(String httpUrl) { + HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost + return sendHttpPost(httpPost); + } + + /** + * 发送 post请求 + * + * @param httpUrl 地址 + * @param params 参数(格式:key1=value1&key2=value2) + */ + public String sendHttpPost(String httpUrl, String params) { + HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost + try { + //设置参数 + StringEntity stringEntity = new StringEntity(params, "UTF-8"); + stringEntity.setContentType("application/x-www-form-urlencoded"); + httpPost.setEntity(stringEntity); + } catch (Exception e) { + e.printStackTrace(); + } + return sendHttpPost(httpPost); + } + + /** + * 发送 post请求 + * + * @param httpUrl 地址 + * @param maps 参数 + */ + public String sendHttpPost(String httpUrl, Map maps) { + HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost + // 创建参数队列 + List nameValuePairs = new ArrayList(); + for (String key : maps.keySet()) { + nameValuePairs.add(new BasicNameValuePair(key, maps.get(key))); + } + try { + httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")); + } catch (Exception e) { + e.printStackTrace(); + } + return sendHttpPost(httpPost); + } + + /** + * 发送Post请求 + * + * @param httpPost + * @return + */ + private String sendHttpPost(HttpPost httpPost) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + HttpEntity entity = null; + String responseContent = null; + try { + // 创建默认的httpClient实例 + httpClient = HttpClients.createDefault(); + httpPost.setConfig(requestConfig); + // 执行请求 + long execStart = System.currentTimeMillis(); + response = httpClient.execute(httpPost); + long execEnd = System.currentTimeMillis(); + System.out.println("=================执行post请求耗时:" + (execEnd - execStart) + "ms"); + long getStart = System.currentTimeMillis(); + entity = response.getEntity(); + responseContent = EntityUtils.toString(entity, "UTF-8"); + long getEnd = System.currentTimeMillis(); + System.out.println("=================获取响应结果耗时:" + (getEnd - getStart) + "ms"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + // 关闭连接,释放资源 + if (response != null) { + response.close(); + } + if (httpClient != null) { + httpClient.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return responseContent; + } + + /** + * 发送 get请求 + * + * @param httpUrl + */ + public String sendHttpGet(String httpUrl) { + HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求 + return sendHttpGet(httpGet); + } + + /** + * 发送 get请求Https + * + * @param httpUrl + */ + public String sendHttpsGet(String httpUrl) { + HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求 + return sendHttpsGet(httpGet); + } + + /** + * 发送Get请求 + * + * @param httpGet + * @return + */ + private String sendHttpGet(HttpGet httpGet) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + HttpEntity entity = null; + String responseContent = null; + try { + // 创建默认的httpClient实例. + + + httpClient = HttpClients.createDefault(); + + httpGet.setConfig(requestConfig); + // 执行请求 + response = httpClient.execute(httpGet); + entity = response.getEntity(); + responseContent = EntityUtils.toString(entity, "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + // 关闭连接,释放资源 + if (response != null) { + response.close(); + } + if (httpClient != null) { + httpClient.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return responseContent; + } + + /** + * 发送Get请求Https + * + * @param httpGet + * @return + */ + private String sendHttpsGet(HttpGet httpGet) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + HttpEntity entity = null; + String responseContent = null; + try { + // 创建默认的httpClient实例. + PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(new URL(httpGet.getURI().toString())); + DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher); + httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build(); + httpGet.setConfig(requestConfig); + // 执行请求 + response = httpClient.execute(httpGet); + entity = response.getEntity(); + responseContent = EntityUtils.toString(entity, "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + // 关闭连接,释放资源 + if (response != null) { + response.close(); + } + if (httpClient != null) { + httpClient.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return responseContent; + } + + /** + * 发送xml数据 + * + * @param url + * @param xmlData + * @return + * @throws ClientProtocolException + * @throws IOException + */ + public static HttpResponse sendXMLDataByPost(String url, String xmlData) + throws ClientProtocolException, IOException { + HttpClient httpClient = HttpClients.createDefault(); + HttpPost httppost = new HttpPost(url); + StringEntity entity = new StringEntity(xmlData); + httppost.setEntity(entity); + httppost.setHeader("Content-Type", "text/xml;charset=UTF-8"); + HttpResponse response = httpClient.execute(httppost); + return response; + } + + /** + * 获得响应HTTP实体内容 + * + * @param response + * @return + * @throws IOException + * @throws UnsupportedEncodingException + */ + public static String getHttpEntityContent(HttpResponse response) throws IOException, UnsupportedEncodingException { + HttpEntity entity = response.getEntity(); + if (entity != null) { + InputStream is = entity.getContent(); + BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + String line = br.readLine(); + StringBuilder sb = new StringBuilder(); + while (line != null) { + sb.append(line + "\n"); + line = br.readLine(); + } + return sb.toString(); + } + return ""; + } + + +} \ No newline at end of file