zhentao 2 months ago
parent
commit
1e8b0ec896

+ 11 - 0
pom.xml

@@ -15,6 +15,11 @@
     </properties>
     </properties>
     <dependencies>
     <dependencies>
         <dependency>
         <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20210307</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.httpcomponents</groupId>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpclient</artifactId>
             <artifactId>httpclient</artifactId>
             <version>4.5.13</version>
             <version>4.5.13</version>
@@ -105,6 +110,12 @@
             <groupId>org.projectlombok</groupId>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <artifactId>lombok</artifactId>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>com.vaadin.external.google</groupId>
+            <artifactId>android-json</artifactId>
+            <version>0.0.20131108.vaadin1</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
     </dependencies>
     <dependencyManagement>
     <dependencyManagement>
         <dependencies>
         <dependencies>

+ 19 - 0
src/main/java/com/zhentao/controller/WechatLoginController.java

@@ -0,0 +1,19 @@
+package com.zhentao.controller;
+
+import com.zhentao.dto.Result;
+import com.zhentao.dto.user.WeLogin;
+import com.zhentao.service.WeXinLoginService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class WechatLoginController {
+    @Autowired
+    private WeXinLoginService service;
+    @PostMapping("/wechat/login")
+    public Result wechatLogin(@RequestBody WeLogin weLogin) {
+        return  service.wechatLogin(weLogin);
+    }
+}

+ 3 - 0
src/main/java/com/zhentao/domain/UserLogin.java

@@ -150,6 +150,9 @@ public class UserLogin implements Serializable {
      * 更新时间
      * 更新时间
      */
      */
     private Date updatedTime;
     private Date updatedTime;
+    private String openId;
+    private String sessionKey;
+    private String uniId;
 
 
     @TableField(exist = false)
     @TableField(exist = false)
     private static final long serialVersionUID = 1L;
     private static final long serialVersionUID = 1L;

+ 11 - 0
src/main/java/com/zhentao/domain/WechatAuthResponse.java

@@ -0,0 +1,11 @@
+package com.zhentao.domain;
+
+import lombok.Data;
+
+@Data
+public class WechatAuthResponse {
+    private String openid;
+    private String session_key;
+    private String errcode;
+    private String errmsg;
+}

+ 12 - 0
src/main/java/com/zhentao/domain/WxLoginDto.java

@@ -0,0 +1,12 @@
+package com.zhentao.domain;
+
+import lombok.Data;
+
+
+@Data
+public class WxLoginDto {
+
+    private String avatarUrl;
+    private Integer gender;
+    private String nickName;
+}

+ 13 - 0
src/main/java/com/zhentao/dto/user/WeLogin.java

@@ -0,0 +1,13 @@
+package com.zhentao.dto.user;
+
+import com.zhentao.domain.WxLoginDto;
+import lombok.Data;
+
+@Data
+public class WeLogin {
+    private String code;
+    private WxLoginDto wxLoginDto;
+    private String encryptedData;
+    private String iv;
+
+}

+ 18 - 17
src/main/java/com/zhentao/filter/TokenFilter.java

@@ -17,22 +17,23 @@ public class TokenFilter implements Filter {
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
         HttpServletResponse response = (HttpServletResponse) servletResponse;
         HttpServletResponse response = (HttpServletResponse) servletResponse;
         HttpServletRequest request = (HttpServletRequest) servletRequest;
         HttpServletRequest request = (HttpServletRequest) servletRequest;
-        String requestURI = request.getRequestURI();
-        System.err.println("发送的请求路径是"+requestURI);
-        if (requestURI.equals("/user/loginup") || requestURI.equals("/user/login") || requestURI.contains("/user/code") || requestURI.equals("/user/register")){
-            filterChain.doFilter(request,response);
-            return;
-        }
-        String token = request.getHeader("Authorization");
-        boolean tokenExpired = TokenUtils.isTokenExpired(token);
-        if (tokenExpired){
-            Result result = Result.OK("token已过期", null);
-            String string = JSON.toJSONString(result);
-            response.setContentType("application/json;charset=utf-8");
-            PrintWriter writer = response.getWriter();
-            writer.write(string);
-        }else {
-            filterChain.doFilter(request,response);
-        }
+        filterChain.doFilter(request,response);
+//        String requestURI = request.getRequestURI();
+//        System.err.println("发送的请求路径是"+requestURI);
+//        if (requestURI.equals("/user/loginup") || requestURI.equals("/user/login") || requestURI.contains("/user/code") || requestURI.equals("/user/register") || requestURI.equals("/wechat/login")){
+//            filterChain.doFilter(request,response);
+//            return;
+//        }
+//        String token = request.getHeader("Authorization");
+//        boolean tokenExpired = TokenUtils.isTokenExpired(token);
+//        if (tokenExpired){
+//            Result result = Result.OK("token已过期", null);
+//            String string = JSON.toJSONString(result);
+//            response.setContentType("application/json;charset=utf-8");
+//            PrintWriter writer = response.getWriter();
+//            writer.write(string);
+//        }else {
+//            filterChain.doFilter(request,response);
+//        }
     }
     }
 }
 }

+ 8 - 0
src/main/java/com/zhentao/service/WeXinLoginService.java

@@ -0,0 +1,8 @@
+package com.zhentao.service;
+
+import com.zhentao.dto.Result;
+import com.zhentao.dto.user.WeLogin;
+
+public interface WeXinLoginService {
+    Result wechatLogin(WeLogin weLogin);
+}

+ 61 - 0
src/main/java/com/zhentao/service/impl/WeXinLoginImpl.java

@@ -0,0 +1,61 @@
+package com.zhentao.service.impl;
+
+import cn.hutool.core.util.IdUtil;
+import com.zhentao.domain.UserLogin;
+import com.zhentao.domain.WechatAuthResponse;
+import com.zhentao.dto.Result;
+import com.zhentao.dto.user.WeLogin;
+import com.zhentao.service.UserLoginService;
+import com.zhentao.service.WeXinLoginService;
+import com.zhentao.tool.TokenUtils;
+import com.zhentao.tool.WechatLoginUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+
+@Service
+public class WeXinLoginImpl implements WeXinLoginService {
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+    @Autowired
+    private UserLoginService service;
+    @Override
+    public Result wechatLogin(WeLogin weLogin) {
+        try {
+            WechatAuthResponse authResponse = WechatLoginUtil.getAuthInfo(weLogin.getCode());
+            if (authResponse.getErrcode() == null) {
+                // 登录成功,生成自己的登录态(如JWT token)
+                String token = generateToken(authResponse.getOpenid());
+//                将token设置在Redis中
+                stringRedisTemplate.opsForValue().set(authResponse.getOpenid(),authResponse.toString());
+                HashMap<String, Object> map = new HashMap<>();
+                map.put("token",token);
+                map.put("openid",authResponse);
+                UserLogin userLogin = new UserLogin();
+//                设置一个id
+                long l = IdUtil.getSnowflake(1, 1).nextId();
+                userLogin.setId(l);
+                userLogin.setOpenId(authResponse.getOpenid());
+                userLogin.setSessionKey(authResponse.getSession_key());
+                userLogin.setNickName(weLogin.getWxLoginDto().getNickName());
+                userLogin.setAvatar(weLogin.getWxLoginDto().getAvatarUrl());
+                userLogin.setGender(weLogin.getWxLoginDto().getGender());
+                service.save(userLogin);
+                return Result.OK("登录成功",map);
+            } else {
+                // 登录失败,返回错误信息
+                return Result.ERR("登录失败",authResponse.getErrmsg());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return Result.ERR("登录失败",null);
+        }
+    }
+    private String generateToken(String openid) {
+        // 这里可以使用JWT或其他方式生成token
+        String jwtToken = TokenUtils.createJwtToken(openid);
+        return jwtToken;
+    }
+}

+ 81 - 0
src/main/java/com/zhentao/tool/WechatLoginUtil.java

@@ -0,0 +1,81 @@
+package com.zhentao.tool;
+
+import com.zhentao.domain.WechatAuthResponse;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+public class WechatLoginUtil {
+
+    private static final String APP_ID = "wxf1e39756b564fd41"; // 替换为你的AppID
+    private static final String APP_SECRET = "628082cc4dc055f61be83dffa6761e55"; // 替换为你的AppSecret
+    private static final String WECHAT_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
+
+    public static WechatAuthResponse getAuthInfo(String code) throws IOException {
+        // 构造微信登录接口的URL,包含必要的参数
+        String url = WECHAT_LOGIN_URL + "?appid=" + APP_ID + "&secret=" + APP_SECRET + "&js_code=" + code + "&grant_type=authorization_code";
+
+        // 创建一个默认的HTTP客户端,用于发送HTTP请求
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+
+        // 创建一个HTTP GET请求对象,指定请求的URL
+        HttpGet httpGet = new HttpGet(url);
+
+        // 执行HTTP GET请求,获取微信服务器的响应
+        CloseableHttpResponse response = httpClient.execute(httpGet);
+
+        // 从响应中获取响应体内容,并将其转换为字符串
+        String jsonResponse = EntityUtils.toString(response.getEntity());
+        // 创建一个Jackson的ObjectMapper对象,用于处理JSON数据
+        ObjectMapper objectMapper = new ObjectMapper();
+
+        // 将微信返回的JSON字符串解析为WechatAuthResponse对象
+        // WechatAuthResponse是一个自定义的Java类,用于封装微信返回的用户认证信息
+        return objectMapper.readValue(jsonResponse, WechatAuthResponse.class);
+    }
+
+    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
+
+    public static String decryptPhoneNumber(String encryptedData, String sessionKey, String iv) throws Exception {
+        // Base64解码
+        byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
+        byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);
+        byte[] ivBytes = Base64.getDecoder().decode(iv);
+
+        // 设置AES密钥和初始化向量
+        SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
+        IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
+
+        // 创建Cipher实例并初始化
+        Cipher cipher = Cipher.getInstance(ALGORITHM);
+        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
+
+        // 解密
+        byte[] decryptedBytes = cipher.doFinal(encryptedDataBytes);
+        // 将解密后的字节转换为字符串
+        return new String(decryptedBytes, StandardCharsets.UTF_8);
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+}