Browse Source

添加微信登录接口

wangmh 7 years ago
parent
commit
b3b4afc966

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

@@ -12,6 +12,7 @@ import com.uas.sso.entity.Token;
 import com.uas.sso.service.*;
 import com.uas.sso.util.*;
 import com.uas.sso.web.waf.request.WafRequestWrapper;
+import com.uas.sso.weixin.service.WeChatService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.ui.ModelMap;
 import org.springframework.util.Assert;
@@ -68,6 +69,9 @@ public class LoginController extends BaseController {
     @Autowired
     private PersonalAccountService personalAccountService;
 
+    @Autowired
+    private WeChatService weChatService;
+
     @RequestMapping(method = RequestMethod.POST)
     public ModelMap login() {
         // 获取登录信息
@@ -737,6 +741,7 @@ public class LoginController extends BaseController {
      */
     private ModelMap login(Long userUU, String appId, String spaceUU, String returnUrl) {
         // 登录
+        appId = StringUtils.isEmpty(appId) ? AccountConfig.ACCOUNT_CENTER : appId;
         App app = appService.findOne(appId);
         if (app == null) {
             throw new VerifyError("应用不存在");
@@ -777,4 +782,46 @@ public class LoginController extends BaseController {
             return loginByUser(userAccount, returnUrl, true);
         }
     }
+
+    /**
+     * 微信获取code
+     * @param code 获取用户信息的code
+     * @param state 验证请求
+     * @return
+     */
+    @RequestMapping(value = "/wxqrLogin", method = RequestMethod.POST)
+    public ModelMap wxqrLogin(String code, String state) {
+        // TODO 校验state
+
+        // 获取用户信息
+        OAuthInfo oAuthInfo = weChatService.getOAuthInfoByCode(code);
+        User user = null;
+        if (oAuthInfo == null || StringUtils.isEmpty(oAuthInfo.getAccess_token())) {
+            Long userUU = (Long) request.getSession().getAttribute("userUU");
+            if (userUU == null) {
+                return error("验证信息过期,请重新扫码登录");
+            }
+            user = new User(userUU);
+        } else {
+            user = userService.findByWxUnionid(oAuthInfo.getUnionid());
+            if (user == null) {
+                // 提示前端用户微信未绑定账号
+                Token token = new Token(oAuthInfo.getUnionid(), oAuthInfo.getExpires_in());
+                ModelMap data = new ModelMap("hasRegister", false);
+                data.put("token", token.getId());
+                return success(data);
+            }
+            request.getSession().setAttribute("userUU", user.getUserUU());
+        }
+
+        // 登录
+        WafRequestWrapper wr = new WafRequestWrapper(request);
+        String appId = wr.getParameter("appId");
+        String spaceUU = wr.getParameter("spaceUU");
+        String returnUrl = wr.getParameter("returnUrl");
+        String baseUrl = wr.getParameter("baseUrl");
+        request.getSession().setAttribute("baseUrl", baseUrl);
+        return success(login(user.getUserUU(), appId, spaceUU, returnUrl));
+    }
+
 }

+ 8 - 1
sso-server/src/main/java/com/uas/sso/controller/PersonalRegisterController.java

@@ -7,6 +7,7 @@ import com.uas.sso.core.Step;
 import com.uas.sso.core.Type;
 import com.uas.sso.core.PasswordStrength;
 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.logging.LoggerManager;
@@ -57,7 +58,7 @@ public class PersonalRegisterController extends BaseController {
      */
     @RequestMapping(method = RequestMethod.POST)
     @ResponseBody
-    public ModelMap register(User user, String appId, String code, String token, String baseUrl) {
+    public ModelMap register(User user, String appId, String code, String token, String baseUrl, String t) {
         // 获取参数
         String vipName = user.getVipName();
         String mobile = user.getMobile();
@@ -87,6 +88,12 @@ public class PersonalRegisterController extends BaseController {
         }
 
         // 注册并添加注册日志
+        if (!StringUtils.isEmpty(t)) {
+            Token unionidToken = tokenService.findOne(t);
+            if (unionidToken != null) {
+                user.setWxUnionid((String) unionidToken.getBind());
+            }
+        }
         appId = StringUtils.isEmpty(appId) ? "sso" : appId;
         user = userService.register(user, appId);
         registerLogger.info(Type.REGISTER_PERSONAL.getValue(), Step.FIRST.getValue(), "个人注册成功", user, user.getFromApp());

+ 8 - 5
sso-server/src/main/java/com/uas/sso/controller/UserspaceRegisterController.java

@@ -8,10 +8,7 @@ import com.uas.sso.core.PasswordStrength;
 import com.uas.sso.core.Status;
 import com.uas.sso.core.Step;
 import com.uas.sso.core.Type;
-import com.uas.sso.entity.App;
-import com.uas.sso.entity.User;
-import com.uas.sso.entity.UserAccount;
-import com.uas.sso.entity.Userspace;
+import com.uas.sso.entity.*;
 import com.uas.sso.logging.LoggerManager;
 import com.uas.sso.logging.RegisterBufferedLogger;
 import com.uas.sso.service.AppService;
@@ -96,7 +93,7 @@ public class UserspaceRegisterController extends BaseController {
      */
     @RequestMapping(method = RequestMethod.POST)
     @ResponseBody
-    public ModelMap register(Userspace userspace, User user, String appId, String baseUrl) {
+    public ModelMap register(Userspace userspace, User user, String appId, String baseUrl, String t) {
         // 获取企业信息
         String spaceName = userspace.getSpaceName();
         String businessCode = userspace.getBusinessCode();
@@ -153,6 +150,12 @@ public class UserspaceRegisterController extends BaseController {
         }
 
         // 企业注册
+        if (!StringUtils.isEmpty(t)) {
+            Token unionidToken = tokenService.findOne(t);
+            if (unionidToken != null) {
+                admin.setWxUnionid((String) unionidToken.getBind());
+            }
+        }
         userspace.setAdmin(admin);
         userspace = userspaceService.register(userspace, appId);
 

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

@@ -56,7 +56,12 @@ public enum Type {
     /**
      * 用户解除绑定企业
      */
-    UNBIND_USERSPACE("UNBIND");
+    UNBIND_USERSPACE("UNBIND"),
+
+    /**
+     * 用户绑定微信账号
+     */
+    BIND_WEIXIN("BINDWEIXIN");
 
     private String value;
 

+ 7 - 0
sso-server/src/main/java/com/uas/sso/dao/UserDao.java

@@ -126,4 +126,11 @@ public interface UserDao extends JpaRepository<User, Long>, JpaSpecificationExec
      */
     @Query("select u.fromApp as appId , count(u) as count from User u where u.fromApp in ?1 group by u.fromApp")
     List<Map<String,Object>> getCountByRegisterDate(List<String> fromApps);
+
+    /**
+     * 根据用户unionID获取用户信息
+     * @param wxUnionid 用户unionID
+     * @return
+     */
+    User findByWxUnionid(String wxUnionid);
 }

+ 69 - 0
sso-server/src/main/java/com/uas/sso/entity/OAuthInfo.java

@@ -0,0 +1,69 @@
+package com.uas.sso.entity;
+
+/**
+ * @author wangmh
+ * @create 2018-06-28 14:18
+ * @desc 微信用户登录信息
+ **/
+public class OAuthInfo {
+
+    private String access_token;
+
+    private Integer expires_in;
+
+    private String refresh_token;
+
+    private String openid;
+
+    private String scope;
+
+    private String unionid;
+
+    public String getAccess_token() {
+        return access_token;
+    }
+
+    public void setAccess_token(String access_token) {
+        this.access_token = access_token;
+    }
+
+    public Integer getExpires_in() {
+        return expires_in;
+    }
+
+    public void setExpires_in(Integer expires_in) {
+        this.expires_in = expires_in;
+    }
+
+    public String getRefresh_token() {
+        return refresh_token;
+    }
+
+    public void setRefresh_token(String refresh_token) {
+        this.refresh_token = refresh_token;
+    }
+
+    public String getOpenid() {
+        return openid;
+    }
+
+    public void setOpenid(String openid) {
+        this.openid = openid;
+    }
+
+    public String getScope() {
+        return scope;
+    }
+
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+
+    public String getUnionid() {
+        return unionid;
+    }
+
+    public void setUnionid(String unionid) {
+        this.unionid = unionid;
+    }
+}

+ 14 - 0
sso-server/src/main/java/com/uas/sso/entity/User.java

@@ -152,6 +152,12 @@ public class User implements Serializable {
     @Column(name = "wx_openid")
     private String wxOpenid;
 
+    /**
+     * 微信号(微信扫码授权或微信客户端授权,不用出现在注册页面,预留)
+     */
+    @Column(name = "wx_unionid", unique = true)
+    private String wxUnionid;
+
     /**
      * qq号(qq扫码或qq客户端授权,不用出现在注册页面,预留)
      */
@@ -397,6 +403,14 @@ public class User implements Serializable {
         this.wxOpenid = wxOpenid;
     }
 
+    public String getWxUnionid() {
+        return wxUnionid;
+    }
+
+    public void setWxUnionid(String wxUnionid) {
+        this.wxUnionid = wxUnionid;
+    }
+
     public Integer getQqNumber() {
         return qqNumber;
     }

+ 23 - 0
sso-server/src/main/java/com/uas/sso/service/UserService.java

@@ -110,6 +110,15 @@ public interface UserService {
      */
     void checkPasswordByEmail(String email, String password, boolean isEncry);
 
+    /**
+     * 根据账号校验优软云密码,不能校验erp的密码
+     * @param username 账号
+     * @param password 密码
+     * @param isEncry 密码是否加密
+     * @return 密码是否正确
+     */
+    boolean checkPasswordByUsername(String username, String password, boolean isEncry);
+
     /**
      * 获得当前账号密码输错次数
      *
@@ -319,4 +328,18 @@ public interface UserService {
      */
     Map<String, Long> countInCurrentWeek(List<String> fromApps);
 
+    /**
+     * 根据用户unionID获取用户信息
+     * @param unionid 用户unionID
+     * @return
+     */
+    User findByWxUnionid(String unionid);
+
+    /**
+     * 微信绑定账号
+     * @param username 用户名
+     * @param password 密码
+     * @param unionid 用户微信唯一标志
+     */
+    void bindUnionId(String username, String password, String unionid);
 }

+ 34 - 0
sso-server/src/main/java/com/uas/sso/service/impl/UserServiceImpl.java

@@ -201,6 +201,17 @@ public class UserServiceImpl implements UserService {
         }
     }
 
+    @Override
+    public boolean checkPasswordByUsername(String username, String password, boolean isEncry) {
+        Assert.hasText(username, "用户名不能为空");
+        Assert.hasText(password, "密码不能为空");
+
+        User user = findByUsername(username);
+        checkPassword(user, password, isEncry);
+
+        return true;
+    }
+
     @Override
     public int getPwdErrorCount(String username) {
         User user = findByUsername(username);
@@ -704,6 +715,29 @@ public class UserServiceImpl implements UserService {
         });
     }
 
+    @Override
+    public User findByWxUnionid(String unionid) {
+        return userDao.findByWxUnionid(unionid);
+    }
+
+    @Override
+    public void bindUnionId(String username, String password, String unionid) {
+        Assert.hasText(username, "用户名不能为空");
+        Assert.hasText(password, "密码不能为空");
+
+        User user = findByUsername(username);
+        if (user == null) {
+            throw new IllegalArgumentException("该用户不存在");
+        }
+
+        checkPassword(user.getUserUU(), password, false);
+
+        user.setWxUnionid(unionid);
+        userDao.save(user);
+
+        userLogger.info(user, Type.BIND_WEIXIN.getValue());
+    }
+
     /**
      * 同步用户信息到各个应用
      * @param user 用户信息

+ 79 - 0
sso-server/src/main/java/com/uas/sso/weixin/controller/WeChatController.java

@@ -0,0 +1,79 @@
+package com.uas.sso.weixin.controller;
+
+import com.uas.sso.controller.BaseController;
+import com.uas.sso.entity.OAuthInfo;
+import com.uas.sso.entity.Token;
+import com.uas.sso.entity.User;
+import com.uas.sso.service.UserService;
+import com.uas.sso.weixin.service.WeChatService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ui.Model;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author wangmh
+ * @create 2018-06-07 11:27
+ * @desc 微信登录
+ **/
+@RequestMapping("/weChat")
+@RestController
+public class WeChatController extends BaseController {
+
+    @Autowired
+    private WeChatService weChatService;
+
+    @Autowired
+    private UserService userService;
+
+    private static final String WX_APPID = "wxa14aec4edce8a2d2";
+
+    private static final String WX_APPSECRET = "9749d2df03eb161f4d4075df69c2e2c9";
+
+    private static final String WX_REDIRECT_URI = "http://sso.ubtob.com/";
+
+    private static final String WX_LOGIN_SCOPE = "snsapi_login";
+
+    @RequestMapping("/getQrUrl")
+    public ModelMap getQrUrl(String appId) {
+        String redirect_uri = "http://sso.ubtob.com/sso/login/wxqrLogin";
+        String url = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
+        url = url.replace("APPID", WX_APPID).replace("REDIRECT_URI", redirect_uri).replace("SCOPE", WX_LOGIN_SCOPE).replace("STATE", "");
+        return success(url);
+    }
+
+    @RequestMapping("/getQrParams")
+    public ModelMap getQrParams(String appId) {
+        ModelMap params = new ModelMap();
+        params.addAttribute("appid", WX_APPID).addAttribute("state", "");
+        return params;
+    }
+
+    /**
+     * 绑定微信账号
+     * @param t 微信登录失败返回的token
+     * @param username 绑定用户名
+     * @param password 绑定密码
+     * @return
+     */
+    @RequestMapping(value = "/addAccount", method = RequestMethod.POST)
+    public ModelMap addAccount(String t, String username, String password) {
+        Token token = tokenService.findOne(t);
+        if (token == null || token.isExpired()) {
+            return error("绑定失败,请重新扫描二维码");
+        }
+
+        userService.bindUnionId(username, password, (String) token.getBind());
+
+        tokenService.delete(t);
+
+        return success();
+    }
+
+}

+ 18 - 0
sso-server/src/main/java/com/uas/sso/weixin/service/WeChatService.java

@@ -0,0 +1,18 @@
+package com.uas.sso.weixin.service;
+
+import com.uas.sso.entity.OAuthInfo;
+
+/**
+ * @author wangmh
+ * @create 2018-06-11 16:54
+ * @desc 微信服务
+ **/
+public interface WeChatService {
+
+    /**
+     * 根据code获取用户的信息
+     * @param code
+     * @return
+     */
+    OAuthInfo getOAuthInfoByCode(String code);
+}

+ 40 - 0
sso-server/src/main/java/com/uas/sso/weixin/service/impl/WeChatServiceImpl.java

@@ -0,0 +1,40 @@
+package com.uas.sso.weixin.service.impl;
+
+import com.alibaba.dubbo.common.URL;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.uas.sso.common.util.HttpUtil;
+import com.uas.sso.entity.OAuthInfo;
+import com.uas.sso.weixin.service.WeChatService;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import static com.uas.sso.common.util.HttpUtil.doGet;
+
+/**
+ * @author wangmh
+ * @create 2018-06-11 16:57
+ * @desc
+ **/
+@Service
+public class WeChatServiceImpl implements WeChatService {
+    @Override
+    public OAuthInfo getOAuthInfoByCode(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", "wxa14aec4edce8a2d2");
+        url = url.replace("SECRET", "9749d2df03eb161f4d4075df69c2e2c9");
+        url = url.replace("CODE", code);
+        try {
+            HttpUtil.ResponseWrap res = HttpUtil.doGet(url);
+            if (res.getContent() != null) {
+                System.out.println(res.getContent().toString());
+                // {"access_token":"xxx","expires_in":7200,"refresh_token":"xxx","openid":"xxx","scope":"snsapi_userinfo","unionid":"xxx"}
+                OAuthInfo oAuthInfo = JSON.parseObject(res.getContent().toString(), OAuthInfo.class);
+                return oAuthInfo;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}