Browse Source

微信碧合获取用户信息合并,添加手机验证码绑定账号接口

wangmh 7 năm trước cách đây
mục cha
commit
5fb98d756c
25 tập tin đã thay đổi với 503 bổ sung142 xóa
  1. 9 9
      sso-server/src/main/java/com/uas/sso/controller/LoginController.java
  2. 6 12
      sso-server/src/main/java/com/uas/sso/controller/PersonalRegisterController.java
  3. 2 10
      sso-server/src/main/java/com/uas/sso/controller/TestController.java
  4. 7 12
      sso-server/src/main/java/com/uas/sso/controller/UserspaceRegisterController.java
  5. 6 1
      sso-server/src/main/java/com/uas/sso/core/Type.java
  6. 0 41
      sso-server/src/main/java/com/uas/sso/foreign/ForeignFactory.java
  7. 0 14
      sso-server/src/main/java/com/uas/sso/foreign/ForeignInfo.java
  8. 0 25
      sso-server/src/main/java/com/uas/sso/foreign/ForeignService.java
  9. 3 1
      sso-server/src/main/java/com/uas/sso/foreign/bihe/controller/BiHeController.java
  10. 13 2
      sso-server/src/main/java/com/uas/sso/foreign/bihe/entity/BiHeInfo.java
  11. 18 1
      sso-server/src/main/java/com/uas/sso/foreign/bihe/entity/BiHeUserInfo.java
  12. 1 1
      sso-server/src/main/java/com/uas/sso/foreign/bihe/service/BiHeService.java
  13. 2 2
      sso-server/src/main/java/com/uas/sso/foreign/bihe/service/impl/BiHeServiceImpl.java
  14. 114 0
      sso-server/src/main/java/com/uas/sso/foreign/controller/ForeignController.java
  15. 36 0
      sso-server/src/main/java/com/uas/sso/foreign/entity/ForeignInfo.java
  16. 13 0
      sso-server/src/main/java/com/uas/sso/foreign/entity/ForeignUserInfo.java
  17. 69 0
      sso-server/src/main/java/com/uas/sso/foreign/factory/ForeignFactory.java
  18. 27 0
      sso-server/src/main/java/com/uas/sso/foreign/service/ForeignService.java
  19. 4 1
      sso-server/src/main/java/com/uas/sso/foreign/weixin/controller/WeChatController.java
  20. 15 2
      sso-server/src/main/java/com/uas/sso/foreign/weixin/entity/OAuthInfo.java
  21. 31 1
      sso-server/src/main/java/com/uas/sso/foreign/weixin/entity/UserInfo.java
  22. 1 1
      sso-server/src/main/java/com/uas/sso/foreign/weixin/service/WeChatService.java
  23. 2 2
      sso-server/src/main/java/com/uas/sso/foreign/weixin/service/impl/WeChatServiceImpl.java
  24. 37 1
      sso-server/src/main/java/com/uas/sso/service/UserService.java
  25. 87 3
      sso-server/src/main/java/com/uas/sso/service/impl/UserServiceImpl.java

+ 9 - 9
sso-server/src/main/java/com/uas/sso/controller/LoginController.java

@@ -4,11 +4,10 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.uas.account.AccountConfig;
 import com.uas.sso.*;
-import com.uas.sso.foreign.ForeignFactory;
-import com.uas.sso.foreign.ForeignInfo;
-import com.uas.sso.foreign.ForeignService;
+import com.uas.sso.foreign.factory.ForeignFactory;
+import com.uas.sso.foreign.entity.ForeignInfo;
+import com.uas.sso.foreign.service.ForeignService;
 import com.uas.sso.foreign.bihe.entity.BiHeInfo;
-import com.uas.sso.foreign.bihe.entity.BiHeResult;
 import com.uas.sso.foreign.bihe.service.BiHeService;
 import com.uas.sso.common.util.HttpUtil;
 import com.uas.sso.core.Const;
@@ -799,11 +798,12 @@ public class LoginController extends BaseController {
      * @return
      */
     @RequestMapping(value = "/wxqrLogin", method = RequestMethod.POST)
+    @Deprecated
     public ModelMap wxqrLogin(@RequestParam(defaultValue = "sso") String appId, String code, String state) {
         // TODO 校验state
 
         // 获取用户信息
-        OAuthInfo oAuthInfo = weChatService.getOAuthInfoByCode(code);
+        OAuthInfo oAuthInfo = weChatService.getForeignInfoByCode(code);
         User user = null;
         if (oAuthInfo == null || StringUtils.isEmpty(oAuthInfo.getAccess_token())) {
             Long userUU = (Long) request.getSession().getAttribute("userUU");
@@ -842,10 +842,11 @@ public class LoginController extends BaseController {
      * @return
      */
     @RequestMapping(value = "/bhLogin", method = RequestMethod.POST)
+    @Deprecated
     public ModelMap bhLogin(@RequestParam(defaultValue = "city") String appId, String code) {
         // 获取用户信息
         User user = null;
-        BiHeInfo oAuthInfo = biHeService.getOAuthInfoByCode(code);
+        BiHeInfo oAuthInfo = biHeService.getForeignInfoByCode(code);
 
         String accessToken = Optional.ofNullable(oAuthInfo).map(BiHeInfo::getAccessToken).orElse(null);
         if (StringUtils.isEmpty(accessToken)) {
@@ -891,7 +892,7 @@ public class LoginController extends BaseController {
         // 获取用户信息
         User user = null;
         ForeignService foreignService = ForeignFactory.getForeignService(type);
-        ForeignInfo foreignInfo = foreignService.getOAuthInfoByCode(code);
+        ForeignInfo foreignInfo = foreignService.getForeignInfoByCode(code);
 
         String accessToken = Optional.ofNullable(foreignInfo).map(ForeignInfo::getForeignAccessToken).orElse(null);
         if (StringUtils.isEmpty(accessToken)) {
@@ -906,7 +907,6 @@ public class LoginController extends BaseController {
             if (user == null) {
                 // 提示前端用户微信未绑定账号
                 ModelMap map = new ModelMap("data", foreignInfo);
-                map.put("type", "bihe");
                 Token token = new Token(map, foreignInfo.getForeignExpiresIn());
                 tokenService.save(token);
                 ModelMap data = new ModelMap("hasRegister", false);
@@ -922,6 +922,6 @@ public class LoginController extends BaseController {
         String returnUrl = wr.getParameter("returnUrl");
         String baseUrl = wr.getParameter("baseUrl");
         request.getSession().setAttribute("baseUrl", baseUrl);
-        return success(login(user.getUserUU(), appId, spaceUU, returnUrl));
+        return success(login(user.getUserUU(), appId, spaceUU, returnUrl)).addAttribute("hasRegister", true);
     }
 }

+ 6 - 12
sso-server/src/main/java/com/uas/sso/controller/PersonalRegisterController.java

@@ -11,6 +11,7 @@ import com.uas.sso.entity.App;
 import com.uas.sso.entity.Token;
 import com.uas.sso.entity.User;
 import com.uas.sso.entity.UserAccount;
+import com.uas.sso.foreign.entity.ForeignInfo;
 import com.uas.sso.logging.LoggerManager;
 import com.uas.sso.logging.RegisterBufferedLogger;
 import com.uas.sso.service.AppService;
@@ -93,19 +94,11 @@ public class PersonalRegisterController extends BaseController {
         // 设置第三方id
         if (!StringUtils.isEmpty(t)) {
             Token unionidToken = tokenService.findOne(t);
-            Optional<ModelMap> optionalMap = Optional.ofNullable(unionidToken).map(value -> (ModelMap) value.getBind());
-            String type = optionalMap.map(value -> (String) value.get("type")).orElse(null);
-            switch (type) {
-                case "weixin":
-                    user.setWxUnionid(optionalMap.map(value -> (OAuthInfo) value.get("data")).map(OAuthInfo::getUnionid).orElse(null));
-                    break;
-                case "bihe":
-                    user.setBhOpenId(optionalMap.map(value -> (BiHeInfo) value.get("data")).map(BiHeInfo::getOpenId).orElse(null));
-                    break;
-                default:
-                    break;
+            Optional<ForeignInfo> foreignInfo = Optional.ofNullable(unionidToken).map(value -> (ModelMap) unionidToken.getBind()).map(value -> (ForeignInfo) value.get("data"));
+            if (!foreignInfo.isPresent()) {
+                return error("参数错误,绑定失败");
             }
-            tokenService.delete(t);
+            userService.setForeignOpenId(user, foreignInfo.get());
         }
 
         // 注册并添加注册日志
@@ -114,6 +107,7 @@ public class PersonalRegisterController extends BaseController {
         registerLogger.info(Type.REGISTER_PERSONAL.getValue(), Step.FIRST.getValue(), "个人注册成功", user, user.getFromApp());
 
         // 注册成功后删除验证码token
+        tokenService.delete(t);
         tokenService.delete(token);
 
         App app = appService.findOne(appId);

+ 2 - 10
sso-server/src/main/java/com/uas/sso/controller/TestController.java

@@ -1,9 +1,5 @@
 package com.uas.sso.controller;
 
-import com.uas.sso.bihe.entity.BiHeResult;
-import com.uas.sso.bihe.entity.BiHeUserInfo;
-import com.uas.sso.bihe.service.BiHeService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -12,13 +8,9 @@ import org.springframework.web.bind.annotation.ResponseBody;
 @RequestMapping("/test")
 public class TestController {
 
-    @Autowired
-    private BiHeService biHeService;
-
     @RequestMapping
     @ResponseBody
-    public void test(String name) {
-        BiHeResult<BiHeUserInfo> biHeResult = biHeService.getUserInfoByAccessToken("fewgwefwef", "fefewfw");
-        System.out.println(biHeResult.toString());
+    public String test(String name) {
+        return "return " + name;
     }
 }

+ 7 - 12
sso-server/src/main/java/com/uas/sso/controller/UserspaceRegisterController.java

@@ -10,6 +10,7 @@ import com.uas.sso.core.Status;
 import com.uas.sso.core.Step;
 import com.uas.sso.core.Type;
 import com.uas.sso.entity.*;
+import com.uas.sso.foreign.entity.ForeignInfo;
 import com.uas.sso.logging.LoggerManager;
 import com.uas.sso.logging.RegisterBufferedLogger;
 import com.uas.sso.service.AppService;
@@ -155,25 +156,19 @@ public class UserspaceRegisterController extends BaseController {
         // 设置第三方id
         if (!StringUtils.isEmpty(t)) {
             Token unionidToken = tokenService.findOne(t);
-            Optional<ModelMap> optionalMap = Optional.ofNullable(unionidToken).map(value -> (ModelMap) value.getBind());
-            String type = optionalMap.map(value -> (String) value.get("type")).orElse(null);
-            switch (type) {
-                case "weixin":
-                    admin.setWxUnionid(optionalMap.map(value -> (OAuthInfo) value.get("data")).map(OAuthInfo::getUnionid).orElse(null));
-                    break;
-                case "bihe":
-                    admin.setBhOpenId(optionalMap.map(value -> (BiHeInfo) value.get("data")).map(BiHeInfo::getOpenId).orElse(null));
-                    break;
-                default:
-                    break;
+            Optional<ForeignInfo> foreignInfo = Optional.ofNullable(unionidToken).map(value -> (ModelMap) unionidToken.getBind()).map(value -> (ForeignInfo) value.get("data"));
+            if (!foreignInfo.isPresent()) {
+                return error("参数错误,绑定失败");
             }
-            tokenService.delete(t);
+            userService.setForeignOpenId(user, foreignInfo.get());
         }
 
         // 企业注册
         userspace.setAdmin(admin);
         userspace = userspaceService.register(userspace, appId);
 
+        tokenService.delete(t);
+
         // 发送邮件和短信
         ModelMap info = new ModelMap();
         info.addAttribute("enname", userspace.getSpaceName());

+ 6 - 1
sso-server/src/main/java/com/uas/sso/core/Type.java

@@ -66,7 +66,12 @@ public enum Type {
     /**
      * 用户绑定微信账号
      */
-    BIND_BIHE("BINDBIHE");
+    BIND_BIHE("BINDBIHE"),
+
+    /**
+     * 用户绑定第三方账号
+     */
+    BIND_FOREIGN("BINDFOREIGN");
 
     private String value;
 

+ 0 - 41
sso-server/src/main/java/com/uas/sso/foreign/ForeignFactory.java

@@ -1,41 +0,0 @@
-package com.uas.sso.foreign;
-
-import com.uas.sso.exception.VisibleError;
-import com.uas.sso.foreign.bihe.service.BiHeService;
-import com.uas.sso.foreign.weixin.service.WeChatService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.PostConstruct;
-
-/**
- * @author: huyy
- * @date: 2018/7/26 16:07
- */
-@Component
-public class ForeignFactory {
-
-    @Autowired
-    private BiHeService biHeService;
-
-    @Autowired
-    private WeChatService weChatService;
-
-    private static ForeignFactory foreignFactory;
-
-    @PostConstruct
-    public void init() {
-        foreignFactory = this;
-    }
-
-    public static ForeignService getForeignService(String type) {
-        switch (type) {
-            case "bh":
-                return foreignFactory.biHeService;
-            case "wx":
-                return foreignFactory.weChatService;
-            default:
-                throw new VisibleError("类型错误");
-        }
-    }
-}

+ 0 - 14
sso-server/src/main/java/com/uas/sso/foreign/ForeignInfo.java

@@ -1,14 +0,0 @@
-package com.uas.sso.foreign;
-
-/**
- * @author: huyy
- * @date: 2018/7/26 16:22
- */
-public abstract class ForeignInfo {
-
-    public abstract String getForeignId();
-
-    public abstract String getForeignAccessToken();
-
-    public abstract int getForeignExpiresIn();
-}

+ 0 - 25
sso-server/src/main/java/com/uas/sso/foreign/ForeignService.java

@@ -1,25 +0,0 @@
-package com.uas.sso.foreign;
-
-import com.uas.sso.foreign.weixin.entity.OAuthInfo;
-import com.uas.sso.foreign.weixin.entity.UserInfo;
-
-/**
- * @author: huyy
- * @date: 2018/7/26 15:40
- */
-public interface ForeignService<T extends ForeignInfo, V> {
-
-    /**
-     *
-     * @param code
-     * @return
-     */
-    T getOAuthInfoByCode(String code);
-
-    /**
-     *
-     * @param oAuthInfo
-     * @return
-     */
-    V findUserByUnionid(T oAuthInfo);
-}

+ 3 - 1
sso-server/src/main/java/com/uas/sso/foreign/bihe/controller/BiHeController.java

@@ -37,6 +37,7 @@ public class BiHeController extends BaseController {
      * @return
      */
     @RequestMapping(value = "/addAccount", method = RequestMethod.POST)
+    @Deprecated
     public ModelMap addAccount(@RequestParam String t, String username, String password) {
         // 获取token
         Token token = tokenService.findOne(t);
@@ -67,6 +68,7 @@ public class BiHeController extends BaseController {
      * @return 碧合用户头像和名称
      */
     @RequestMapping(value = "/userInfo/{token}",method = RequestMethod.GET)
+    @Deprecated
     public ModelMap findUserByToken(@PathVariable("token") String t) {
         // 获取token
         Token token = tokenService.findOne(t);
@@ -80,7 +82,7 @@ public class BiHeController extends BaseController {
         }
 
         // 根据AccessToken获取用户信息
-        BiHeUserInfo userRoot = biHeService.findUserByUnionid(biHeInfo.get());
+        BiHeUserInfo userRoot = biHeService.findUserByForeignInfo(biHeInfo.get());
         return success(userRoot);
     }
 

+ 13 - 2
sso-server/src/main/java/com/uas/sso/foreign/bihe/entity/BiHeInfo.java

@@ -1,6 +1,8 @@
 package com.uas.sso.foreign.bihe.entity;
 
-import com.uas.sso.foreign.ForeignInfo;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.uas.sso.foreign.entity.ForeignInfo;
+import com.uas.sso.foreign.factory.ForeignFactory;
 
 import java.io.Serializable;
 
@@ -21,6 +23,7 @@ public class BiHeInfo extends ForeignInfo implements Serializable {
 
     private String openId;
 
+    @JSONField(serialize = false)
     public String getAccessToken() {
         return accessToken;
     }
@@ -29,6 +32,7 @@ public class BiHeInfo extends ForeignInfo implements Serializable {
         this.accessToken = accessToken;
     }
 
+    @JSONField(serialize = false)
     public Integer getExpires_in() {
         return expires_in;
     }
@@ -37,6 +41,7 @@ public class BiHeInfo extends ForeignInfo implements Serializable {
         this.expires_in = expires_in;
     }
 
+    @JSONField(serialize = false)
     public String getRefreshToken() {
         return refreshToken;
     }
@@ -45,6 +50,7 @@ public class BiHeInfo extends ForeignInfo implements Serializable {
         this.refreshToken = refreshToken;
     }
 
+    @JSONField(serialize = false)
     public String getOpenId() {
         return openId;
     }
@@ -54,7 +60,7 @@ public class BiHeInfo extends ForeignInfo implements Serializable {
     }
 
     @Override
-    public String getForeignId() {
+    public String getForeignOpenId() {
         return this.getOpenId();
     }
 
@@ -67,4 +73,9 @@ public class BiHeInfo extends ForeignInfo implements Serializable {
     public int getForeignExpiresIn() {
         return this.getExpires_in();
     }
+
+    @Override
+    protected String getType() {
+        return ForeignFactory.TYPE_BIHE;
+    }
 }

+ 18 - 1
sso-server/src/main/java/com/uas/sso/foreign/bihe/entity/BiHeUserInfo.java

@@ -1,5 +1,9 @@
 package com.uas.sso.foreign.bihe.entity;
 
+import com.alibaba.fastjson.annotation.JSONField;
+import com.uas.sso.foreign.entity.ForeignUserInfo;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
 import java.io.Serializable;
 
 /**
@@ -7,7 +11,7 @@ import java.io.Serializable;
  * @author: huyy
  * @date: 2018/7/19 9:46
  */
-public class BiHeUserInfo implements Serializable {
+public class BiHeUserInfo extends ForeignUserInfo implements Serializable {
 
     private static final long serialVersionUID = -7330561061690671703L;
 
@@ -17,6 +21,7 @@ public class BiHeUserInfo implements Serializable {
 
     private String nickName;
 
+    @JSONField(serialize = false)
     public String getUserPhone() {
         return userPhone;
     }
@@ -25,6 +30,7 @@ public class BiHeUserInfo implements Serializable {
         this.userPhone = userPhone;
     }
 
+    @JSONField(serialize = false)
     public String getUserImg() {
         return userImg;
     }
@@ -33,6 +39,7 @@ public class BiHeUserInfo implements Serializable {
         this.userImg = userImg;
     }
 
+    @JSONField(serialize = false)
     public String getNickName() {
         return nickName;
     }
@@ -40,4 +47,14 @@ public class BiHeUserInfo implements Serializable {
     public void setNickName(String nickName) {
         this.nickName = nickName;
     }
+
+    @Override
+    public String getForeignUserImg() {
+        return this.userImg;
+    }
+
+    @Override
+    public String getForeignUserName() {
+        return this.nickName;
+    }
 }

+ 1 - 1
sso-server/src/main/java/com/uas/sso/foreign/bihe/service/BiHeService.java

@@ -1,6 +1,6 @@
 package com.uas.sso.foreign.bihe.service;
 
-import com.uas.sso.foreign.ForeignService;
+import com.uas.sso.foreign.service.ForeignService;
 import com.uas.sso.foreign.bihe.entity.BiHeInfo;
 import com.uas.sso.foreign.bihe.entity.BiHeOrder;
 import com.uas.sso.foreign.bihe.entity.BiHeUserInfo;

+ 2 - 2
sso-server/src/main/java/com/uas/sso/foreign/bihe/service/impl/BiHeServiceImpl.java

@@ -28,7 +28,7 @@ public class BiHeServiceImpl implements BiHeService {
      * @return
      */
     @Override
-    public BiHeInfo getOAuthInfoByCode(String code){
+    public BiHeInfo getForeignInfoByCode(String code){
         String url = "https://opengwtest.bgycc.com/open/oauth/token";
         Map<String, String> map = new HashMap<>(3);
         map.put("code", code);
@@ -53,7 +53,7 @@ public class BiHeServiceImpl implements BiHeService {
      * @return
      */
     @Override
-    public BiHeUserInfo findUserByUnionid(BiHeInfo bihinfo) {
+    public BiHeUserInfo findUserByForeignInfo(BiHeInfo bihinfo) {
         String url = "https://opengwtest.bgycc.com/open/open/user";
         Map<String, String>map = new HashMap<>(3);
         map.put("accessToken", bihinfo.getAccessToken());

+ 114 - 0
sso-server/src/main/java/com/uas/sso/foreign/controller/ForeignController.java

@@ -0,0 +1,114 @@
+package com.uas.sso.foreign.controller;
+
+import com.uas.sso.controller.BaseController;
+import com.uas.sso.entity.Token;
+import com.uas.sso.entity.User;
+import com.uas.sso.exception.VisibleError;
+import com.uas.sso.foreign.bihe.entity.BiHeInfo;
+import com.uas.sso.foreign.bihe.entity.BiHeUserInfo;
+import com.uas.sso.foreign.entity.ForeignInfo;
+import com.uas.sso.foreign.entity.ForeignUserInfo;
+import com.uas.sso.foreign.factory.ForeignFactory;
+import com.uas.sso.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Optional;
+import java.util.function.Function;
+
+/**
+ * @author wangmh
+ * @create 2018-07-30 14:09
+ * @desc 第三方controller
+ **/
+@RestController
+@RequestMapping("/foreign")
+public class ForeignController extends BaseController {
+
+    @Autowired
+    private UserService userService;
+
+    /**
+     * 通过用户名密码绑定第三方账号
+     * @param token 存放第三方校验信息
+     * @param username 用户名
+     * @param password 密码
+     * @return
+     */
+    @PostMapping(value = "/addAccount", params = "_operate=account")
+    public ModelMap addAccount(@RequestParam(name = "t") String token, String username, String password) {
+        addAccount(token, foreignInfo -> userService.bindForeignOpenId(username, password, foreignInfo));
+        return success();
+    }
+
+    /**
+     * 绑定第三方账号
+     * @param token 存放第三方校验信息
+     * @param code 验证码
+     * @param mobile 手机号
+     * @param codeToken 存放手机号获取的验证码
+     * @return
+     */
+    @PostMapping(value = "/addAccount", params = "_operate=code")
+    public ModelMap addAccount(@RequestParam(name = "t") String token, String code, String mobile, @RequestParam(name = "token") String codeToken) {
+        addAccount(token, foreignInfo -> userService.bindForeignOpenId(code, mobile, codeToken, foreignInfo));
+        return success();
+    }
+
+    /**
+     * 绑定账号
+     * @param token 存放第三方校验信息
+     * @param mapper 绑定用户信息方法回调
+     * @return 用户信息
+     */
+    private User addAccount(String token, Function<ForeignInfo, User> mapper) {
+        // 获取token
+        Token existToken = tokenService.findOne(token);
+        if (existToken == null || existToken.isExpired()) {
+            throw new VisibleError("绑定失败,校验信息失效");
+        }
+
+        // 获取accessToken
+        ModelMap data = (ModelMap) existToken.getBind();
+        Optional<ForeignInfo> foreignInfo = Optional.ofNullable(data).map(value -> (ForeignInfo) value.get("data"));
+        if (!foreignInfo.isPresent()) {
+            throw new VisibleError("绑定失败,参数错误");
+        }
+
+        // 绑定openId
+        User user = mapper.apply(foreignInfo.get());
+        request.getSession().setAttribute("userUU", user.getUserUU());
+
+        // 删除token
+        tokenService.delete(token);
+
+        return user;
+    }
+
+    /**
+     * 获取用户
+     * @param token tokenId,存储第三方校验信息
+     * @return 用户头像和名称
+     */
+    @GetMapping(value = "/userInfo/{token}")
+    public ModelMap findUserByToken(@PathVariable("token") String token) {
+        // 获取token
+        Token existToken = tokenService.findOne(token);
+        if (existToken == null || existToken.isExpired()) {
+            throw new VisibleError("验证信息过期");
+        }
+
+        // 获取token中碧合AccessToken信息
+        ModelMap data = (ModelMap) existToken.getBind();
+        Optional<ForeignInfo> foreignInfo = Optional.ofNullable(data).map(value -> (ForeignInfo) value.get("data"));
+        if (!foreignInfo.isPresent()) {
+            return error("参数错误,绑定失败");
+        }
+
+        // 根据AccessToken获取用户信息
+        ForeignUserInfo userInfo = foreignInfo.get().getForeignService().findUserByForeignInfo(foreignInfo.get());
+        return success(userInfo);
+    }
+
+}

+ 36 - 0
sso-server/src/main/java/com/uas/sso/foreign/entity/ForeignInfo.java

@@ -0,0 +1,36 @@
+package com.uas.sso.foreign.entity;
+
+import com.uas.sso.foreign.factory.ForeignFactory;
+import com.uas.sso.foreign.service.ForeignService;
+
+/**
+ * 第三方openId实例
+ * @author: huyy
+ * @date: 2018/7/26 16:22
+ */
+public abstract class ForeignInfo {
+
+    /**
+     * 获得第三方openId(第三方用户唯一标志)
+     * @return openId
+     */
+    public abstract String getForeignOpenId();
+
+    /**
+     * 获取第三方accessToken
+     * @return accessToken
+     */
+    public abstract String getForeignAccessToken();
+
+    /**
+     * 获取第三方accessToken有效期
+     * @return 有效时间(单位:s)
+     */
+    public abstract int getForeignExpiresIn();
+
+    public ForeignService getForeignService() {
+        return ForeignFactory.getForeignService(getType());
+    }
+
+    protected abstract String getType();
+}

+ 13 - 0
sso-server/src/main/java/com/uas/sso/foreign/entity/ForeignUserInfo.java

@@ -0,0 +1,13 @@
+package com.uas.sso.foreign.entity;
+
+/**
+ * @author wangmh
+ * @create 2018-07-30 14:05
+ * @desc 第三方用户信息
+ **/
+public abstract class ForeignUserInfo {
+
+    public abstract String getForeignUserImg();
+
+    public abstract String getForeignUserName();
+}

+ 69 - 0
sso-server/src/main/java/com/uas/sso/foreign/factory/ForeignFactory.java

@@ -0,0 +1,69 @@
+package com.uas.sso.foreign.factory;
+
+import com.uas.sso.exception.VisibleError;
+import com.uas.sso.foreign.bihe.entity.BiHeInfo;
+import com.uas.sso.foreign.entity.ForeignInfo;
+import com.uas.sso.foreign.service.ForeignService;
+import com.uas.sso.foreign.bihe.service.BiHeService;
+import com.uas.sso.foreign.weixin.entity.OAuthInfo;
+import com.uas.sso.foreign.weixin.service.WeChatService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * 第三方工厂
+ * @author: huyy
+ * @date: 2018/7/26 16:07
+ */
+@Component
+public class ForeignFactory {
+
+    @Autowired
+    private BiHeService biHeService;
+
+    @Autowired
+    private WeChatService weChatService;
+
+    public static final String TYPE_BIHE = "bh";
+
+    public static final String TYPE_WEIXIN = "wx";
+
+    private static ForeignFactory foreignFactory;
+
+    @PostConstruct
+    public void init() {
+        foreignFactory = this;
+    }
+
+    /**
+     * 根据type获取对应的第三方service
+     * @param type type
+     * @return 第三方service
+     */
+    public static ForeignService getForeignService(String type) {
+        switch (type) {
+            case TYPE_BIHE:
+                return foreignFactory.biHeService;
+            case TYPE_WEIXIN:
+                return foreignFactory.weChatService;
+            default:
+                throw new VisibleError("类型错误");
+        }
+    }
+    /**
+     * 根据第三方授权信息获取对应的第三方service
+     * @param foreignInfo 第三方授权信息
+     * @return 第三方service
+     */
+    public static <T extends ForeignInfo> ForeignService getForeignService(T foreignInfo) {
+        if (foreignInfo instanceof BiHeInfo) {
+            return getForeignService(TYPE_BIHE);
+        } else if (foreignInfo instanceof OAuthInfo) {
+            return getForeignService(TYPE_WEIXIN);
+        } else {
+            throw new VisibleError("类型错误");
+        }
+    }
+}

+ 27 - 0
sso-server/src/main/java/com/uas/sso/foreign/service/ForeignService.java

@@ -0,0 +1,27 @@
+package com.uas.sso.foreign.service;
+
+import com.uas.sso.entity.User;
+import com.uas.sso.foreign.entity.ForeignInfo;
+import com.uas.sso.foreign.entity.ForeignUserInfo;
+
+/**
+ * 第三方service
+ * @author: huyy
+ * @date: 2018/7/26 15:40
+ */
+public interface ForeignService<T extends ForeignInfo, V extends ForeignUserInfo> {
+
+    /**
+     * 根据code获取第三方授权信息
+     * @param code 第三方提供的code
+     * @return
+     */
+    T getForeignInfoByCode(String code);
+
+    /**
+     * 根据第三方授权获取第三方用户信息
+     * @param foreignInfo 第三方授权
+     * @return
+     */
+    V findUserByForeignInfo(T foreignInfo);
+}

+ 4 - 1
sso-server/src/main/java/com/uas/sso/foreign/weixin/controller/WeChatController.java

@@ -78,7 +78,9 @@ public class WeChatController extends BaseController {
      * @return
      */
     @RequestMapping(value = "/addAccount", method = RequestMethod.POST)
+    @Deprecated
     public ModelMap addAccount(@RequestParam String t, String username, String password) {
+        // 获取token
         Token token = tokenService.findOne(t);
         if (token == null || token.isExpired()) {
             return error("绑定失败,请重新扫描二维码");
@@ -98,6 +100,7 @@ public class WeChatController extends BaseController {
     }
 
     @RequestMapping(value = "/userInfo/{token}", method = RequestMethod.GET)
+    @Deprecated
     public ModelMap findUserByToken(@PathVariable("token") String t) {
         Token token = tokenService.findOne(t);
         Assert.notNull(token, "验证信息过期,请重新扫码");
@@ -108,7 +111,7 @@ public class WeChatController extends BaseController {
             return error("参数错误,绑定失败");
         }
 
-        UserInfo userInfo = weChatService.findUserByUnionid(oAuthInfo.get());
+        UserInfo userInfo = weChatService.findUserByForeignInfo(oAuthInfo.get());
         return success(userInfo);
     }
 }

+ 15 - 2
sso-server/src/main/java/com/uas/sso/foreign/weixin/entity/OAuthInfo.java

@@ -1,6 +1,8 @@
 package com.uas.sso.foreign.weixin.entity;
 
-import com.uas.sso.foreign.ForeignInfo;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.uas.sso.foreign.entity.ForeignInfo;
+import com.uas.sso.foreign.factory.ForeignFactory;
 
 import java.io.Serializable;
 
@@ -25,6 +27,7 @@ public class OAuthInfo extends ForeignInfo implements Serializable{
 
     private String unionid;
 
+    @JSONField(serialize = false)
     public String getAccess_token() {
         return access_token;
     }
@@ -33,6 +36,7 @@ public class OAuthInfo extends ForeignInfo implements Serializable{
         this.access_token = access_token;
     }
 
+    @JSONField(serialize = false)
     public Integer getExpires_in() {
         return expires_in;
     }
@@ -41,6 +45,7 @@ public class OAuthInfo extends ForeignInfo implements Serializable{
         this.expires_in = expires_in;
     }
 
+    @JSONField(serialize = false)
     public String getRefresh_token() {
         return refresh_token;
     }
@@ -49,6 +54,7 @@ public class OAuthInfo extends ForeignInfo implements Serializable{
         this.refresh_token = refresh_token;
     }
 
+    @JSONField(serialize = false)
     public String getOpenid() {
         return openid;
     }
@@ -57,6 +63,7 @@ public class OAuthInfo extends ForeignInfo implements Serializable{
         this.openid = openid;
     }
 
+    @JSONField(serialize = false)
     public String getScope() {
         return scope;
     }
@@ -65,6 +72,7 @@ public class OAuthInfo extends ForeignInfo implements Serializable{
         this.scope = scope;
     }
 
+    @JSONField(serialize = false)
     public String getUnionid() {
         return unionid;
     }
@@ -74,7 +82,7 @@ public class OAuthInfo extends ForeignInfo implements Serializable{
     }
 
     @Override
-    public String getForeignId() {
+    public String getForeignOpenId() {
         return this.getUnionid();
     }
 
@@ -87,4 +95,9 @@ public class OAuthInfo extends ForeignInfo implements Serializable{
     public int getForeignExpiresIn() {
         return this.getExpires_in();
     }
+
+    @Override
+    protected String getType() {
+        return ForeignFactory.TYPE_WEIXIN;
+    }
 }

+ 31 - 1
sso-server/src/main/java/com/uas/sso/foreign/weixin/entity/UserInfo.java

@@ -1,5 +1,10 @@
 package com.uas.sso.foreign.weixin.entity;
 
+import com.alibaba.fastjson.annotation.JSONField;
+import com.uas.sso.foreign.entity.ForeignUserInfo;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+import java.io.Serializable;
 import java.util.List;
 
 /**
@@ -7,7 +12,9 @@ import java.util.List;
  * @create 2018-07-02 15:54
  * @desc 微信用户信息
  **/
-public class UserInfo {
+public class UserInfo extends ForeignUserInfo implements Serializable {
+
+    private static final long serialVersionUID = -1030751248733243391L;
 
     private String openid;
 
@@ -29,6 +36,7 @@ public class UserInfo {
 
     private String unionid;
 
+    @JSONField(serialize = false)
     public String getOpenid() {
         return openid;
     }
@@ -37,6 +45,7 @@ public class UserInfo {
         this.openid = openid;
     }
 
+    @JSONField(serialize = false)
     public String getNickname() {
         return nickname;
     }
@@ -45,6 +54,7 @@ public class UserInfo {
         this.nickname = nickname;
     }
 
+    @JSONField(serialize = false)
     public String getSex() {
         return sex;
     }
@@ -53,6 +63,7 @@ public class UserInfo {
         this.sex = sex;
     }
 
+    @JSONField(serialize = false)
     public String getLanguage() {
         return language;
     }
@@ -61,6 +72,7 @@ public class UserInfo {
         this.language = language;
     }
 
+    @JSONField(serialize = false)
     public String getCity() {
         return city;
     }
@@ -69,6 +81,7 @@ public class UserInfo {
         this.city = city;
     }
 
+    @JSONField(serialize = false)
     public String getProvince() {
         return province;
     }
@@ -77,6 +90,7 @@ public class UserInfo {
         this.province = province;
     }
 
+    @JSONField(serialize = false)
     public String getCountry() {
         return country;
     }
@@ -85,6 +99,8 @@ public class UserInfo {
         this.country = country;
     }
 
+    @JsonIgnore
+    @JSONField(serialize = false)
     public String getHeadimgurl() {
         return headimgurl;
     }
@@ -93,6 +109,8 @@ public class UserInfo {
         this.headimgurl = headimgurl;
     }
 
+    @JsonIgnore
+    @JSONField(serialize = false)
     public List<String> getPrivilege() {
         return privilege;
     }
@@ -101,6 +119,8 @@ public class UserInfo {
         this.privilege = privilege;
     }
 
+    @JsonIgnore
+    @JSONField(serialize = false)
     public String getUnionid() {
         return unionid;
     }
@@ -108,4 +128,14 @@ public class UserInfo {
     public void setUnionid(String unionid) {
         this.unionid = unionid;
     }
+
+    @Override
+    public String getForeignUserImg() {
+        return this.headimgurl;
+    }
+
+    @Override
+    public String getForeignUserName() {
+        return this.nickname;
+    }
 }

+ 1 - 1
sso-server/src/main/java/com/uas/sso/foreign/weixin/service/WeChatService.java

@@ -1,6 +1,6 @@
 package com.uas.sso.foreign.weixin.service;
 
-import com.uas.sso.foreign.ForeignService;
+import com.uas.sso.foreign.service.ForeignService;
 import com.uas.sso.foreign.weixin.entity.OAuthInfo;
 import com.uas.sso.foreign.weixin.entity.UserInfo;
 

+ 2 - 2
sso-server/src/main/java/com/uas/sso/foreign/weixin/service/impl/WeChatServiceImpl.java

@@ -18,7 +18,7 @@ import static com.uas.sso.common.util.HttpUtil.doGet;
 @Service
 public class WeChatServiceImpl implements WeChatService {
     @Override
-    public OAuthInfo getOAuthInfoByCode(String code) {
+    public OAuthInfo getForeignInfoByCode(String code) {
         String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
         url= url.replace("APPID", WXParam.DEFAULT_APPID);
         url = url.replace("SECRET", WXParam.DEFAULT_APPSECRET);
@@ -38,7 +38,7 @@ public class WeChatServiceImpl implements WeChatService {
     }
 
     @Override
-    public UserInfo findUserByUnionid(OAuthInfo oAuthInfo) {
+    public UserInfo findUserByForeignInfo(OAuthInfo oAuthInfo) {
         String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
         url = url.replace("ACCESS_TOKEN", oAuthInfo.getAccess_token()).replace("OPENID", oAuthInfo.getOpenid());
         try {

+ 37 - 1
sso-server/src/main/java/com/uas/sso/service/UserService.java

@@ -4,7 +4,7 @@ import com.uas.sso.entity.User;
 import com.uas.sso.entity.UserQuestion;
 import com.uas.sso.entity.UserRecord;
 import com.uas.sso.entity.UserSpaceDetailInfo;
-import com.uas.sso.foreign.ForeignInfo;
+import com.uas.sso.foreign.entity.ForeignInfo;
 import org.springframework.data.domain.Page;
 
 import java.sql.Timestamp;
@@ -334,6 +334,7 @@ public interface UserService {
      * @param unionid 用户unionID
      * @return
      */
+    @Deprecated
     User findByWxUnionid(String unionid);
 
     /**
@@ -341,6 +342,7 @@ public interface UserService {
      * @param openId 用户openId
      * @return
      */
+    @Deprecated
     User findByBhOpenId(String openId);
 
     /**
@@ -349,6 +351,7 @@ public interface UserService {
      * @param password 密码
      * @param unionid 用户微信唯一标志
      */
+    @Deprecated
     User bindUnionId(String username, String password, String unionid);
 
     /**
@@ -357,7 +360,40 @@ public interface UserService {
      * @param password 密码
      * @param openId 用户微信唯一标志
      */
+    @Deprecated
     User bindBhOpenId(String username, String password, String openId);
 
+    /**
+     * 根据第三方授权信息获取用户信息
+     * @param foreignInfo 第三方授权信息
+     * @return
+     */
     User findByForeignId(ForeignInfo foreignInfo);
+
+    /**
+     * 根据用户名密码绑定第三方openId
+     * @param username 用户名
+     * @param password 密码
+     * @param foreignInfo 第三方openId
+     * @return 用户信息
+     */
+    User bindForeignOpenId(String username, String password, ForeignInfo foreignInfo);
+
+    /**
+     * 通过手机验证码绑定第三方openId
+     * @param code 验证码
+     * @param mobile 手机号
+     * @param codeToken 获取验证码返回的token
+     * @param foreignInfo 第三方授权信息
+     * @return
+     */
+    User bindForeignOpenId(String code, String mobile, String codeToken, ForeignInfo foreignInfo);
+
+    /**
+     * 设置用户第三方id
+     * @param user 用户信息
+     * @param foreignInfo 第三方授权信息
+     * @return
+     */
+    User setForeignOpenId(User user, ForeignInfo foreignInfo);
 }

+ 87 - 3
sso-server/src/main/java/com/uas/sso/service/impl/UserServiceImpl.java

@@ -11,7 +11,7 @@ import com.uas.sso.dao.UserDao;
 import com.uas.sso.dao.UserRecordDao;
 import com.uas.sso.entity.*;
 import com.uas.sso.exception.VisibleError;
-import com.uas.sso.foreign.ForeignInfo;
+import com.uas.sso.foreign.entity.ForeignInfo;
 import com.uas.sso.foreign.bihe.entity.BiHeInfo;
 import com.uas.sso.foreign.weixin.entity.OAuthInfo;
 import com.uas.sso.i.CountCallBack;
@@ -71,6 +71,9 @@ public class UserServiceImpl implements UserService {
     @Autowired
     private UserQuestionService userQuestionService;
 
+    @Autowired
+    private TokenService tokenService;
+
     private UserBufferedLogger userLogger = LoggerManager.getLogger(UserBufferedLogger.class);
 
     private SyncBufferedLogger syncLogger = LoggerManager.getLogger(SyncBufferedLogger.class);
@@ -772,10 +775,91 @@ public class UserServiceImpl implements UserService {
     public User findByForeignId(ForeignInfo foreignInfo) {
         User user = null;
         if (foreignInfo instanceof OAuthInfo) {
-            user = userDao.findByWxUnionid(foreignInfo.getForeignId());
+            user = userDao.findByWxUnionid(foreignInfo.getForeignOpenId());
         } else if (foreignInfo instanceof BiHeInfo) {
-            user = userDao.findByBhOpenId(foreignInfo.getForeignId());
+            user = userDao.findByBhOpenId(foreignInfo.getForeignOpenId());
+        }
+        return user;
+    }
+
+    @Override
+    public User bindForeignOpenId(String username, String password, ForeignInfo foreignInfo) {
+        // 校验空参数
+        try {
+            Assert.hasText(username, "用户名不能为空");
+            Assert.hasText(password, "密码不能为空");
+        } catch (IllegalArgumentException e) {
+            throw new VisibleError(e.getMessage());
+        }
+
+        // 校验用户名密码是否正确
+        User user = findByUsername(username);
+        if (user == null) {
+            throw new VisibleError("该用户不存在");
+        }
+        checkPassword(user.getUserUU(), password, false);
+
+        // 设置第三方openId
+        setForeignOpenId(user, foreignInfo);
+        userDao.save(user);
+
+        userLogger.info(user, Type.BIND_FOREIGN.getValue());
+        return user;
+    }
+
+    @Override
+    public User bindForeignOpenId(String code, String mobile, String codeToken, ForeignInfo foreignInfo) {
+        // 校验空参数
+        try {
+            Assert.hasText(code, "验证码不能为空");
+            Assert.hasText(mobile, "手机号不能为空");
+            Assert.hasText(codeToken, "token不能为空");
+        } catch (IllegalArgumentException e) {
+            throw new VisibleError(e.getMessage());
+        }
+
+        // 校验验证码是否正确
+        Token existToken = tokenService.findOne(codeToken);
+        if (existToken == null || existToken.isExpired()) {
+            throw new VisibleError("验证码过期");
         }
+        if (!mobile.equals(existToken.getMobile())) {
+            throw new VisibleError("手机号已被修改,请重新获取验证码");
+        }
+        if (!code.equals(existToken.getBind())) {
+            throw new VisibleError("验证码不正确,请重新输入");
+        }
+
+        // 设置第三方openId
+        User user = userDao.findByMobile(mobile);
+        if (user == null) {
+            throw new VisibleError("该用户不存在");
+        }
+        setForeignOpenId(user, foreignInfo);
+        userDao.save(user);
+
+        userLogger.info(user, Type.BIND_FOREIGN.getValue());
+        return user;
+    }
+
+    /**
+     * 设置用户第三方openId,不同应用对应不同字段
+     * @param user 用户信息
+     * @param foreignInfo
+     * @return
+     */
+    @Override
+    public User setForeignOpenId(User user, ForeignInfo foreignInfo) {
+        if (user == null) {
+            return null;
+        }
+
+        if (foreignInfo instanceof OAuthInfo) {
+            user.setWxUnionid(foreignInfo.getForeignOpenId());
+        } else if (foreignInfo instanceof BiHeInfo) {
+            user.setBhOpenId(foreignInfo.getForeignOpenId());
+        }
+
         return user;
     }