소스 검색

20190716微信小程序登录

suochencheng 6 년 전
부모
커밋
036fd5ade2

+ 25 - 0
pom.xml

@@ -993,6 +993,31 @@
             <version>3.3.49.ALL</version>
         </dependency>
 
+
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-miniapp</artifactId>
+            <version>3.4.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-mp</artifactId>
+            <version>3.4.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-pay</artifactId>
+            <version>3.4.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-open</artifactId>
+            <version>3.4.0</version>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 26 - 0
src/main/java/com/izouma/awesomeadmin/container/WeixinConfig.java

@@ -0,0 +1,26 @@
+package com.izouma.awesomeadmin.container;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
+import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig;
+import com.izouma.awesomeadmin.util.PropertiesFileLoader;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class WeixinConfig {
+
+    @Bean
+    public WxMaService wxMaService() {
+        WxMaInMemoryConfig config = new WxMaInMemoryConfig();
+        config.setAppid(PropertiesFileLoader.getProperties("weixinappid"));
+        config.setSecret(PropertiesFileLoader.getProperties("weixinsecret"));
+//        config.setToken("");
+//        config.setAesKey("");
+        config.setMsgDataFormat("json");
+
+        WxMaService service = new WxMaServiceImpl();
+        service.setWxMaConfig(config);
+        return service;
+    }
+}

+ 12 - 1
src/main/java/com/izouma/awesomeadmin/dao/UserInfoMapper.xml

@@ -38,6 +38,7 @@
         <result column="house_card" property="houseCard" jdbcType="INTEGER"/>
         <result column="recommender" property="recommender" jdbcType="INTEGER"/>
         <result column="money_ticket" property="moneyTicket" jdbcType="INTEGER"/>
+        <result column="session_key" property="sessionKey" jdbcType="VARCHAR"/>
 
         <association property="departId" javaType="string" column="id"
                      select="com.izouma.awesomeadmin.dao.DepartInfoMapper.getUserDepartId"/>
@@ -82,6 +83,7 @@
         <result column="house_card" property="houseCard" jdbcType="INTEGER"/>
         <result column="recommender" property="recommender" jdbcType="INTEGER"/>
         <result column="money_ticket" property="moneyTicket" jdbcType="INTEGER"/>
+        <result column="session_key" property="sessionKey" jdbcType="VARCHAR"/>
     </resultMap>
 
     <sql id="Base_Column_List">
@@ -89,7 +91,7 @@
         country, province, city, district, create_time, del_flag, money_coin, money_point,
         contacter, contact_phone, company_name, company_type, admin_flag, cash_pledge,
         approve_flag, store_flag, company_flag, approve_step, notice_flag, remind_flag,
-        create_flag, level_id, house_card, recommender, money_ticket
+        create_flag, level_id, house_card, recommender, money_ticket,session_key
     </sql>
     <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">
         select
@@ -217,6 +219,9 @@
             <if test="moneyTicket != null">
                 money_ticket,
             </if>
+            <if test="sessionKey != null">
+                session_key,
+            </if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="id != null">
@@ -330,6 +335,9 @@
             <if test="moneyTicket != null">
                 #{moneyTicket},
             </if>
+            <if test="sessionKey != null">
+                #{sessionKey},
+            </if>
         </trim>
     </insert>
     <update id="updateByPrimaryKeySelective" parameterType="com.izouma.awesomeadmin.model.UserInfo">
@@ -443,6 +451,9 @@
             <if test="moneyTicket != null">
                 money_ticket = #{moneyTicket},
             </if>
+            <if test="sessionKey != null">
+                session_key = #{sessionKey},
+            </if>
         </set>
         where id = #{id,jdbcType=INTEGER}
     </update>

+ 10 - 0
src/main/java/com/izouma/awesomeadmin/model/UserInfo.java

@@ -93,6 +93,8 @@ public class UserInfo {
 
     private Integer moneyTicket;
 
+    private String sessionKey;
+
 
     public String getDepartId() {
         return departId;
@@ -414,5 +416,13 @@ public class UserInfo {
     public void setMoneyTicket(Integer moneyTicket) {
         this.moneyTicket = moneyTicket;
     }
+
+    public String getSessionKey() {
+        return sessionKey;
+    }
+
+    public void setSessionKey(String sessionKey) {
+        this.sessionKey = sessionKey;
+    }
 }
 

+ 4 - 0
src/main/java/com/izouma/awesomeadmin/service/UserInfoService.java

@@ -46,5 +46,9 @@ public interface UserInfoService {
     void alipaySuccess(String tradeNo, String tradeStatus);
 
     Result weiren(UserInfo record);
+
+    UserInfo loginMiniApp(String code) throws UserInfoServiceImpl.LoginException;
+
+    Result getMiniAppUserInfo(String sessionKey, String rawData, String signature, String encryptedData, String iv);
 }
 

+ 97 - 0
src/main/java/com/izouma/awesomeadmin/service/impl/UserInfoServiceImpl.java

@@ -1,5 +1,8 @@
 package com.izouma.awesomeadmin.service.impl;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
 import com.izouma.awesomeadmin.constant.AppConstant;
 import com.izouma.awesomeadmin.dao.*;
 import com.izouma.awesomeadmin.dto.Page;
@@ -18,11 +21,13 @@ import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.security.Keys;
 import io.rong.RongCloud;
 import io.rong.models.SMSVerifyCodeResult;
+import org.apache.commons.lang.RandomStringUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import javax.crypto.SecretKey;
@@ -59,6 +64,11 @@ public class UserInfoServiceImpl implements UserInfoService {
     @Autowired
     private RecommenderLogMapper recommenderLogMapper;
 
+
+    @Autowired
+    @Lazy
+    private WxMaService wxMaService;
+
     @Override
     public List<UserInfo> getUserInfoList(UserInfo record) {
 
@@ -591,5 +601,92 @@ public class UserInfoServiceImpl implements UserInfoService {
 
     }
 
+    @Override
+    public UserInfo loginMiniApp(String code) {
+        try {
+            WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(code);
+            String openId = result.getOpenid();
+            String sessionKey = result.getSessionKey();
+
+            UserInfo userInfo = new UserInfo();
+            userInfo.setOpenId(openId);
+            userInfo = getUserInfo(userInfo);
+
+            if (userInfo != null) {
+                userInfo.setSessionKey(sessionKey);
+                updateUserInfo(userInfo);
+                return userInfo;
+            }
+            userInfo = new UserInfo();
+            userInfo.setUsername(UUID.randomUUID().toString());
+            userInfo.setNickname("用户" + RandomStringUtils.randomAlphabetic(6));
+            userInfo.setOpenId(openId);
+            userInfo.setIcon("https://microball.oss-cn-hangzhou.aliyuncs.com/awesomeAdmin/user.png");
+            userInfo.setSessionKey(sessionKey);
+
+            createUserInfo(userInfo);
+            return userInfo;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+    @Override
+    public Result getMiniAppUserInfo(String sessionKey, String rawData, String signature,
+                                     String encryptedData, String iv) {
+        // 用户信息校验
+        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
+            return new Result(false, "获取用户信息失败");
+        }
+
+        // 解密用户信息
+        WxMaUserInfo wxUserInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
+
+        UserInfo userInfo = new UserInfo();
+        userInfo.setOpenId(wxUserInfo.getOpenId());
+        userInfo = getUserInfo(userInfo);
+
+        String avatarUrl = "https://microball.oss-cn-hangzhou.aliyuncs.com/awesomeAdmin/user.png";
+        try {
+            avatarUrl = saveAvatar(wxUserInfo.getAvatarUrl());
+        } catch (Exception e) {
+            logger.error("获取头像失败", e);
+        }
+
+        if (userInfo == null) {
+
+            userInfo = new UserInfo();
+            userInfo.setUsername(UUID.randomUUID().toString());
+            userInfo.setNickname(wxUserInfo.getNickName());
+            userInfo.setOpenId(wxUserInfo.getOpenId());
+            userInfo.setUnionId(wxUserInfo.getUnionId());
+            userInfo.setIcon(avatarUrl);
+            userInfo.setSex(Integer.valueOf(wxUserInfo.getGender()) == 1 ? "男" : "女");
+            userInfo.setCountry(wxUserInfo.getCountry());
+            userInfo.setProvince(wxUserInfo.getProvince());
+            userInfo.setCity(wxUserInfo.getCity());
+
+            createUserInfo(userInfo);
+
+        } else {
+            userInfo.setIcon(avatarUrl);
+            userInfo.setNickname(wxUserInfo.getNickName());
+            userInfo.setUnionId(wxUserInfo.getUnionId());
+            userInfo.setSex(Integer.valueOf(wxUserInfo.getGender()) == 1 ? "男" : "女");
+            userInfo.setCountry(wxUserInfo.getCountry());
+            userInfo.setProvince(wxUserInfo.getProvince());
+            userInfo.setCity(wxUserInfo.getCity());
+            updateUserInfo(userInfo);
+        }
+
+        if (userInfo != null) {
+            return new Result(true, userInfo);
+        }
+
+        return new Result(false, "获取用户信息失败");
+    }
+
 }
 

+ 23 - 0
src/main/java/com/izouma/awesomeadmin/shiro/MiniAppRealm.java

@@ -0,0 +1,23 @@
+package com.izouma.awesomeadmin.shiro;
+
+import com.izouma.awesomeadmin.model.UserInfo;
+import com.izouma.awesomeadmin.service.impl.UserInfoServiceImpl;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+
+public class MiniAppRealm extends BaseRealm {
+
+    @Override
+    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
+        UserInfo userInfo = null;
+        MiniAppToken miniAppToken = (MiniAppToken) token;
+        try {
+            userInfo = userInfoService.loginMiniApp(miniAppToken.getCode());
+            return new SimpleAuthenticationInfo(userInfo, token.getCredentials(), this.getName());
+        } catch (UserInfoServiceImpl.LoginException e) {
+            throw new AuthenticationException(e.getMessage());
+        }
+    }
+}

+ 32 - 0
src/main/java/com/izouma/awesomeadmin/shiro/MiniAppToken.java

@@ -0,0 +1,32 @@
+package com.izouma.awesomeadmin.shiro;
+
+import org.apache.shiro.authc.AuthenticationToken;
+
+public class MiniAppToken implements AuthenticationToken {
+    private String code;
+
+    public MiniAppToken() {
+    }
+
+    public MiniAppToken(String code) {
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    @Override
+    public Object getPrincipal() {
+        return code;
+    }
+
+    @Override
+    public Object getCredentials() {
+        return code;
+    }
+}

+ 20 - 0
src/main/java/com/izouma/awesomeadmin/web/AuthenticationController.java

@@ -1,8 +1,10 @@
 package com.izouma.awesomeadmin.web;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
 import com.izouma.awesomeadmin.dao.SysAppTokenMapper;
 import com.izouma.awesomeadmin.dto.Result;
 import com.izouma.awesomeadmin.model.UserInfo;
+import com.izouma.awesomeadmin.shiro.MiniAppToken;
 import com.izouma.awesomeadmin.shiro.PhoneCodeToken;
 import com.izouma.awesomeadmin.util.CookieUtil;
 import com.izouma.awesomeadmin.util.PropertiesFileLoader;
@@ -40,6 +42,7 @@ public class AuthenticationController {
     @Autowired
     private SysAppTokenMapper sysAppTokenMapper;
 
+
     @RequestMapping(value = "/image", method = RequestMethod.GET)
     @ResponseBody
     public Result image(HttpServletRequest request, HttpServletResponse response) {
@@ -110,6 +113,23 @@ public class AuthenticationController {
         return result;
     }
 
+    @RequestMapping(value = "/loginMiniApp", method = RequestMethod.POST)
+    @ResponseBody
+    public ModelAndView loginMiniApp(@RequestParam("code") String code,
+                                     @RequestParam(value = "remember", required = false, defaultValue = "false") boolean remember,
+                                     @RequestParam(value = "requireToken", required = false, defaultValue = "false") boolean requireToken,
+                                     HttpServletRequest request,
+                                     HttpServletResponse response) {
+
+        //String rand = (String) request.getSession(true).getAttribute("aliMsgCode");
+
+        ModelAndView result = new ModelAndView(new MappingJackson2JsonView());
+        MiniAppToken miniAppToken = new MiniAppToken(code);
+        Map<String, Object> map = login(miniAppToken, remember, requireToken, 3, request, response);
+        result.addAllObjects(map);
+        return result;
+    }
+
     @RequiresAuthentication
     @RequestMapping(value = "/logout", method = RequestMethod.POST)
     @ResponseBody

+ 12 - 0
src/main/java/com/izouma/awesomeadmin/web/UserInfoController.java

@@ -234,6 +234,18 @@ public class UserInfoController {
         }
     }
 
+    @RequestMapping(value = "/getMiniAppUserInfo", method = RequestMethod.POST)
+    @ResponseBody
+    public Result getMiniAppUserInfo(@RequestParam("sessionKey") String sessionKey,
+                                     @RequestParam("rawData") String rawData,
+                                     @RequestParam("signature") String signature,
+                                     @RequestParam("encryptedData") String encryptedData,
+                                     @RequestParam("iv") String iv) {
+
+        return userInfoService.getMiniAppUserInfo(sessionKey, rawData, signature, encryptedData, iv);
+
+    }
+
 
 }
 

+ 6 - 0
src/main/resources/spring/beans-shiro.xml

@@ -24,6 +24,7 @@
                 <ref bean="userPasswordRealm"/>
                 <ref bean="appTokenRealm"/>
                 <ref bean="wechatRealm"/>
+                <ref bean="miniAppRealm"/>
             </list>
         </property>
         <!--<property name="subjectFactory" ref="agileSubjectFactory"/>-->
@@ -40,6 +41,7 @@
                 <ref bean="userPasswordRealm"/>
                 <ref bean="appTokenRealm"/>
                 <ref bean="wechatRealm"/>
+                <ref bean="miniAppRealm"/>
             </list>
         </property>
     </bean>
@@ -61,6 +63,10 @@
         <property name="authenticationTokenClass" value="com.izouma.awesomeadmin.shiro.WechatToken"/>
     </bean>
 
+    <bean id="miniAppRealm" class="com.izouma.awesomeadmin.shiro.MiniAppRealm">
+        <property name="authenticationTokenClass" value="com.izouma.awesomeadmin.shiro.MiniAppToken"/>
+    </bean>
+
     <bean id="agileSubjectFactory" class="com.izouma.awesomeadmin.shiro.AgileSubjectFactory"/>
 
     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

+ 2 - 0
src/main/resources/spring/spring-mvc.xml

@@ -91,6 +91,8 @@
     </bean>
     <bean id="exceptionResolver" class="com.izouma.awesomeadmin.shiro.MyExceptionResolver"/>
 
+    <bean id="weixinConfig" class="com.izouma.awesomeadmin.container.WeixinConfig"/>
+
     <!-- dwz静态资源管理  -->
     <mvc:resources mapping="/js/**" location="/js/"/>
     <mvc:resources mapping="/images/**" location="/images/"/>