Forráskód Böngészése

1。添加注销账户操作(手机,邮箱)
2。添加账户注销苹果验证操作,添加p8文件
3。添加user_delete_log字段
4。修改登陆返回appleid

a0000 2 éve
szülő
commit
cc153b90fe

+ 47 - 5
src/main/java/com/YuyeTech/TPlat/game/userinfo/controller/ManagerController.java

@@ -48,11 +48,53 @@ public class ManagerController {
     @Autowired
     private UserInfoService userInfoService;
 
-//    /**
-//     * 删除用户数据
-//     * @param userId
-//     * @return
-//     */
+    /**
+     * 通过类型来判断删除
+     * 1。电话:密码或者验证码
+     * 2。邮箱:密码或者验证码
+     * 3。微信:微信授权code
+     * 4。苹果:苹果授权code
+     * @param userId
+     * @param data
+     * @param request
+     * @return
+     */
+    @PostMapping("/deleteUserByType")
+    public ResultVO deleteUserByType(@RequestParam("userId") String userId,
+                               @RequestParam("data")String data,
+                               HttpServletRequest request){
+
+        //1.删除token
+        String headToken = request.getHeader("token");
+        log.info("{}",request.getParameterValues("userId")[0]);
+        if (StringUtils.isNotBlank(headToken)) {
+            log.info(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+            Boolean bSuccess = redisTemplate.delete(String.format(RedisConstant.TOKEN_PREFIX, headToken));
+            if (!bSuccess) {
+                //删除不成功,redis不存在,是非法token
+                log.info("redis 没有对应的token");
+                return ResultVOUtil.error(ResultEnum.TOKEN_IS_ILLEGAL.getCode(), ResultEnum.TOKEN_IS_ILLEGAL.getMessage());
+            }
+        }
+        //2.删除头像W
+        UserInfo userInfo = userInfoService.findUserInfoById(userId, false);
+        if (!userInfo.getAvatarUrl().equals("publicAvatar/defaultAvatar.png") && userInfo.getAvatarUrl() != null && userInfo.getAvatarUrl().length() != 0) {
+            if (aliyunOSSUtil.deleteBlog(userInfo.getAvatarUrl())) {
+                log.info("删除头像成功");
+            }
+        }
+        //3.删除数据库数据
+        mainInfoService.deleteMainInfoById(userId);
+
+        return ResultVOUtil.success();
+    }
+    /**
+     * 删除用户数据
+     * 用户需要输入密码验证(假如是原始密码则通过手机验证码验证)或者验证码来删除用户
+     * 如果微信和ios登陆,看看如何处理
+     * @param userId
+     * @return
+     */
 //    @GetMapping("/deleteUser")
 //    public ResultVO deleteUser(@RequestParam("userId") String userId,
 //                               HttpServletRequest request) {

+ 10 - 0
src/main/java/com/YuyeTech/TPlat/game/userinfo/service/MainInfoServiceImpl.java

@@ -2,6 +2,7 @@ package com.YuyeTech.TPlat.game.userinfo.service;
 
 import cn.hutool.core.date.DateUtil;
 import com.YuyeTech.TPlat.common.service.CommonServiceImpl;
+import com.YuyeTech.TPlat.dataobject.FriendInfo;
 import com.YuyeTech.TPlat.enums.PictureType;
 import com.YuyeTech.TPlat.enums.UserDeleteStatus;
 import com.YuyeTech.TPlat.game.TP_AppleInfo.projo.AppleInfo;
@@ -22,6 +23,7 @@ import com.YuyeTech.TPlat.game.userinfo.repository.MainInfoRepository;
 import com.YuyeTech.TPlat.game.userinfo.vo.MainInfoVo;
 import com.YuyeTech.TPlat.game.TP_AppleInfo.service.AppleInfoService;
 import com.YuyeTech.TPlat.game.TP_WxInfo.service.WxInfoService;
+import com.YuyeTech.TPlat.service.FriendInfoService;
 import com.YuyeTech.TPlat.utils.AliyunOSSUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -62,6 +64,9 @@ public class MainInfoServiceImpl extends CommonServiceImpl<MainInfoVo, MainInfo,
     @Autowired
     private UserDeleteLogService userDeleteLogService;
 
+    @Autowired
+    private FriendInfoService friendInfoService;
+
 
     @Override
     public MainInfo findMainInfoById(String userId) {
@@ -146,12 +151,17 @@ public class MainInfoServiceImpl extends CommonServiceImpl<MainInfoVo, MainInfo,
                     userDeleteLog.setAppleId(appleInfo.getAppleId());
                     appleInfoService.delete(appleInfo.getUserId());
                 }
+                //删除微信信息
                 WxInfoVo wxInfo = wxInfoService.getVo(userId);
                 if (wxInfo != null) {
                     userDeleteLog.setOpenid(wxInfo.getOpenid());
                     userDeleteLog.setUnionid(wxInfo.getUnionid());
                     wxInfoService.delete(wxInfo.getUserId());
                 }
+                //删除其他玩家添加的好友关系,friendID 字段相关删除即可。其他暂不做处理
+                //这里friendId 传入自己的id
+                friendInfoService.deleteFriendInfosByFriendId(userId);
+
                 userDeleteLog.setUpdateTime(DateUtil.date());
                 //记录一个log状态
                 userDeleteLog.setStatus(UserDeleteStatus.PENDING.ordinal());

+ 1 - 0
src/main/java/com/YuyeTech/TPlat/repository/FriendInfoRepository.java

@@ -15,4 +15,5 @@ public interface FriendInfoRepository extends JpaRepository<FriendInfo,String> {
 
     void deleteByUserIdAndFriendId(String userId,String friendId);
 
+    void deleteAllByFriendId(String friendId);
 }

+ 2 - 0
src/main/java/com/YuyeTech/TPlat/service/FriendInfoService.java

@@ -17,6 +17,8 @@ public interface FriendInfoService {
 
     void deleteFriendInfo(String userId,String friendId);
 
+    void deleteFriendInfosByFriendId(String friendId);
+
     void deleteById(String id);
 
 

+ 12 - 0
src/main/java/com/YuyeTech/TPlat/service/impl/FriendInfoServiceImpl.java

@@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 
@@ -39,6 +40,17 @@ public class FriendInfoServiceImpl implements FriendInfoService {
         friendInfoRepository.deleteByUserIdAndFriendId(userId, friendId);
     }
 
+    /**
+     * 这里传入的friendId就是用户自己的userId,用来删除别人添加自己好友的信息
+     * @param friendId
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteFriendInfosByFriendId(String friendId) {
+        friendInfoRepository.deleteAllByFriendId(friendId);
+    }
+
+
     @Override
     public void deleteById(String id) {
         friendInfoRepository.deleteById(id);

+ 151 - 2
src/main/java/com/YuyeTech/TPlat/utils/AppleUtil.java

@@ -5,11 +5,23 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.auth0.jwk.Jwk;
 import io.jsonwebtoken.*;
+import io.jsonwebtoken.impl.DefaultJwtBuilder;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.binary.Base64;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.*;
+import org.springframework.util.MultiValueMap;
 import org.springframework.web.client.RestTemplate;
 
+import java.io.*;
+import java.security.Key;
+import java.security.KeyFactory;
 import java.security.PublicKey;
+import java.security.spec.EncodedKeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * @author:slambb
@@ -18,6 +30,22 @@ import java.security.PublicKey;
 
 @Slf4j
 public class AppleUtil {
+    @Value("${apple.KEYS_URL}")
+    private static String APPLE_KEYS_URL;
+    //Revoke tokens
+    //由于苹果注册后,删除用户需要revoke tokens
+    public static String privateKeyStr;
+    @Value("${apple.REVOKE_TOKENS_URL}")
+    private static String APPLE_REVOKE_TOKENS_URL;
+    @Value("${apple.AUTH_TOKENS_URL}")
+    private static String APPLE_AUTH_TOKENS_URL;
+
+    @Value("${apple.TEAM_ID}")
+    private static String APPLE_TEAM_ID;
+    @Value("${apple.KID}")
+    private static String APPLE_KID;
+    @Value("${apple.BUNDLE_IDENTIFIER}")
+    private static String APPLE_BUNDLE_IDENTIFIER;
 
     /**
      * 获取苹果的公钥
@@ -25,9 +53,9 @@ public class AppleUtil {
      * @throws Exception
      */
     private static JSONArray getAuthKeys() throws Exception {
-        String url = "https://appleid.apple.com/auth/keys";
+//        String url = "https://appleid.apple.com/auth/keys";
         RestTemplate restTemplate = new RestTemplate();
-        JSONObject json = restTemplate.getForObject(url,JSONObject.class);
+        JSONObject json = restTemplate.getForObject(APPLE_KEYS_URL,JSONObject.class);
         JSONArray arr = json.getJSONArray("keys");
         return arr;
     }
@@ -107,4 +135,125 @@ public class AppleUtil {
         return  jsonObject;
     }
 
+
+    /**
+     * 获取p8文件中的内容
+     *
+     * @return
+     */
+    private static Key getPrivateKey() {
+        try {
+            ClassPathResource resource = new ClassPathResource("static/config/AuthKey_8G9994KW4L.p8");
+            InputStream inputStream = resource.getInputStream();
+            Reader reader = new InputStreamReader(inputStream, "utf-8");
+            BufferedReader br = new BufferedReader(reader);
+            String string = null;
+            StringBuffer sb = new StringBuffer();
+            while ((string = br.readLine()) != null) {
+                if (string.startsWith("---")) {
+                    continue;
+                }
+                sb.append(string);
+            }
+            br.close();
+
+            KeyFactory factory = KeyFactory.getInstance("EC");
+            EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(org.apache.commons.codec.binary.Base64.decodeBase64(sb.toString().replaceAll("\\n", "")));
+            return factory.generatePrivate(keySpec);
+        } catch (FileNotFoundException e) {
+            log.error("not find p8 file !=>{}", e.getMessage());
+            return null;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 私钥加密后给苹果去验证,构造clientSecret,就是构造一个jwt字符串
+     * [获取私钥]
+     *
+     * @param iss team_id
+     * @param sub client_id
+     * @param kid access_token
+     * @return
+     */
+    public static String buildJwt(String iss, String sub, String kid) {
+        Map<String, Object> header = new HashMap<>();
+        header.put("alg", SignatureAlgorithm.ES256.getValue()); //SHA256withECDSA
+        header.put("kid", kid);
+
+        long iat = System.currentTimeMillis() / 1000; //以秒为单位
+        Map<String, Object> claims = new HashMap<>();
+        claims.put("iss", iss);// apple开发组id 问ios开发要
+        claims.put("iat", iat);
+        claims.put("exp", iat + 180 * 3600); //设置过期时间
+        claims.put("aud", "https://appleid.apple.com"); //固定值
+        claims.put("sub", sub);// Bundle Identifier
+        return new DefaultJwtBuilder().setHeader(header).setClaims(claims).signWith(SignatureAlgorithm.ES256, getPrivateKey()).compact();
+    }
+
+    /**
+     * 用户授权获取
+     *
+     * @param code
+     * @return
+     */
+    public static String getAuthToken(String code) {
+        if (code.isEmpty() ) {
+            return null;
+        }
+//        JSONObject jsonObject = null;
+        try {
+            privateKeyStr = buildJwt(APPLE_TEAM_ID, APPLE_BUNDLE_IDENTIFIER, APPLE_KID);
+            Map<String, String> stringStringHashMap = new HashMap<>();
+            stringStringHashMap.put("client_id", APPLE_BUNDLE_IDENTIFIER);
+            stringStringHashMap.put("client_secret", privateKeyStr);
+            stringStringHashMap.put("code", code);
+            stringStringHashMap.put("grant_type", "authorization_code");
+
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+            HttpEntity request = new HttpEntity<>(stringStringHashMap,headers);
+            RestTemplate restTemplate = new RestTemplate();
+            JSONObject jsonObject = restTemplate.postForObject(APPLE_AUTH_TOKENS_URL,request,JSONObject.class);
+            return jsonObject.get("access_token").toString();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    public static Boolean appleRevoke(String code) {
+        try {
+            String authToken = getAuthToken(code);
+            Map<String, String> requestMap = new HashMap<>();
+            requestMap.put("client_id", APPLE_BUNDLE_IDENTIFIER);
+            requestMap.put("client_secret", privateKeyStr);
+            requestMap.put("token", authToken);
+            requestMap.put("token_type_hint", "access_token");
+            System.out.println(requestMap);
+
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+            HttpEntity request = new HttpEntity<>(requestMap,headers);
+            RestTemplate restTemplate = new RestTemplate();
+            ResponseEntity<String> responseEntity = restTemplate.postForEntity(APPLE_REVOKE_TOKENS_URL,request,String.class);
+            int statusCode = responseEntity.getStatusCodeValue();
+            if (statusCode != 200) {
+                JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
+                String error = jsonObject.get("error").toString();
+                System.out.println("error --------- " + error);
+                if (!error.isEmpty()) {
+                    return false;
+                }
+            }
+        } catch (Exception e) {
+            log.error("revoke token error");
+            return false;
+        }
+        return true;
+    }
+
+
 }

+ 11 - 1
src/main/resources/application.yml

@@ -1,6 +1,6 @@
 spring:
   profiles:
-    active: prd
+    active: dev
   application:
     name: TPlat
 
@@ -123,3 +123,13 @@ RSA:
     privateKey: "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAjAwN8bgZS_ULhLAwvA5Gz_-l1f7xnt-2mufodT4bCNXsCF4eHDBWr7mQJu7_Ou4llIdj6AulJs0Iu6U1TqwlgQIDAQABAkAf3IY3ngizTTano2YTArR9kc3q16uk14S1zVkHg2-nHJ29ssveNeb8bPg012WhtNltIbr2MsL4_X-Rg7tmM8ihAiEAzSTAIl8SlmHXUnmsvXImq2nVDrIYuNutcpPtZq313d0CIQCuxAQDWEPzSuWhMg5T5YNUFbIFrpZ-5HmUl60lcFeF9QIhAKfjUscObcTbEAB0idWFTXZtp6teP_NR_bJOtDSbXCOVAiEApP1ayImYxOQNe6vVCPFhlY1R3rlfTPaHrXewN-siRc0CIH06t7CE3KQQKv1p1UdEJjPm685ES8IRuFdJEiGJZiex"
 
 cache: '{"user":60,"dept":30}'  #自定义某些缓存空间的过期时间
+
+apple:
+  KID: 8G9994KW4L
+  TEAM_ID: CT63XZVXP2
+  BUNDLE_IDENTIFIER: com.YuyeTech.HeartRate
+  REVOKE_TOKENS_URL: https://appleid.apple.com/auth/revoke
+  AUTH_TOKENS_URL: https://appleid.apple.com/auth/token
+  KEYS_URL: https://appleid.apple.com/auth/keys
+
+

+ 6 - 0
src/main/resources/config/AuthKey_8G9994KW4L.p8

@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgmXLh35Im/y8hL2k+
+nFMifKkzrJEosEe2/nK6Y89bPS+gCgYIKoZIzj0DAQehRANCAASVGIXHEqqkeum3
+YTFXYjqRlicL9CrGQYS/o2fr17C9CeTy5t+iZ+1g3WeSOTTNfOBU/z/PL4yncwpg
+Ti/u96i3
+-----END PRIVATE KEY-----