com.gitlab.summercattle.addons.wechat.auth.service.impl.UserServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cattle-addons-wechat-starter Show documentation
Show all versions of cattle-addons-wechat-starter Show documentation
Cattle Framework Addons WeChat Component
The newest version!
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gitlab.summercattle.addons.wechat.auth.service.impl;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.gitlab.summercattle.addons.wechat.auth.service.UserBindAuthType;
import com.gitlab.summercattle.addons.wechat.auth.service.UserInfo;
import com.gitlab.summercattle.addons.wechat.auth.service.UserService;
import com.gitlab.summercattle.addons.wechat.bind.BindUserInfo;
import com.gitlab.summercattle.addons.wechat.bind.UserBindHandle;
import com.gitlab.summercattle.addons.wechat.bind.UserBindObjectType;
import com.gitlab.summercattle.addons.wechat.common.AppType;
import com.gitlab.summercattle.addons.wechat.common.AbstractUserSession;
import com.gitlab.summercattle.addons.wechat.common.service.WeChatService;
import com.gitlab.summercattle.addons.wechat.configure.WeChatConfigProperties;
import com.gitlab.summercattle.addons.wechat.constants.WeChatConstants;
import com.gitlab.summercattle.addons.wechat.constants.WeChatExceptionConstants;
import com.gitlab.summercattle.addons.wechat.memory.CaptchaMemoryService;
import com.gitlab.summercattle.addons.wechat.memory.SessionMemoryService;
import com.gitlab.summercattle.addons.wechat.miniprogram.configure.MiniProgramConfigProperties;
import com.gitlab.summercattle.addons.wechat.store.UserBindInfo;
import com.gitlab.summercattle.addons.wechat.store.UserBindStoreService;
import com.gitlab.summercattle.commons.exception.CommonException;
import com.gitlab.summercattle.commons.utils.spring.RestTemplateUtils;
/**
* 用户服务实现
* @author orange
*
*/
@Service
public class UserServiceImpl implements UserService {
private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
@Autowired(required = false)
private UserBindHandle userBindHandle;
@Autowired
private WeChatConfigProperties weChatConfigProperties;
@Autowired(required = false)
private MiniProgramConfigProperties miniProgramConfigProperties;
@Autowired
private UserBindStoreService userBindStoreService;
@Autowired
private CaptchaMemoryService captchaMemoryService;
@Autowired
private SessionMemoryService sessionMemoryService;
@Autowired
private WeChatService weChatService;
@Autowired
@Qualifier(WeChatConstants.REST_TEMPLATE_UTILS_NAME)
private RestTemplateUtils restTemplateUtils;
@Override
public void generateBindCaptcha(String source, String sessionId, UserBindObjectType objectType, String userObject, int captchaLength,
Map parameters) throws CommonException {
AbstractUserSession session = getSession(source, sessionId);
if (session == null) {
throw new CommonException("会话标识'" + sessionId + "'不存在");
}
if (session.isBindUser()) {
throw new CommonException("用户已经绑定");
}
if (captchaLength <= 0) {
throw new CommonException("验证码长度必须大于零");
}
if (userBindHandle == null) {
throw new CommonException("用户绑定处理为空");
}
String captcha = captchaMemoryService.get(source, sessionId);
int captchaTimeout = weChatConfigProperties.getCaptchaTimeout();
if (StringUtils.isBlank(captcha)) {
captcha = com.gitlab.summercattle.commons.utils.auxiliary.StringUtils.getRandomString(true, captchaLength);
captchaMemoryService.save(source, sessionId, captcha, captchaTimeout);
userBindHandle.sendCaptcha(objectType, userObject, captcha, captchaTimeout, parameters);
}
else {
userBindHandle.resendCaptcha(objectType, userObject, captcha, parameters);
}
}
@Override
public void bind(String source, String sessionId, UserBindObjectType objectType, UserBindAuthType authType, String userObject, String authInfo,
Map parameters) throws CommonException {
AbstractUserSession session = getSession(source, sessionId);
if (session == null) {
throw new CommonException("会话标识'" + sessionId + "'不存在");
}
if (session.isBindUser()) {
throw new CommonException("用户已经绑定");
}
if (objectType == null) {
throw new CommonException("用户绑定对象类型为空");
}
if (authType == null) {
throw new CommonException("用户绑定验证类型为空");
}
if (StringUtils.isBlank(userObject)) {
throw new CommonException("用户对象为空");
}
if (StringUtils.isBlank(authInfo)) {
throw new CommonException("验证信息为空");
}
if (userBindHandle == null) {
throw new CommonException("用户绑定处理为空");
}
boolean autoCreate = false;
BindUserInfo bindUserInfo = userBindHandle.process(objectType, userObject, parameters);
if (bindUserInfo == null) {
if (userBindHandle.isAutoCreated(objectType, parameters)) {
bindUserInfo = userBindHandle.create(objectType, userObject, parameters);
autoCreate = true;
}
}
if (bindUserInfo == null) {
userBindHandle.bindingFailed();
}
if (!autoCreate) {
if (authType == UserBindAuthType.Captcha) {
String captcha = captchaMemoryService.get(source, sessionId);
if (StringUtils.isBlank(captcha) || !captcha.equals(authInfo)) {
throw new CommonException("验证码失效");
}
captchaMemoryService.invalid(source, sessionId);
}
else if (authType == UserBindAuthType.Password) {
userBindHandle.verifyPassword(objectType, userObject, authInfo, parameters);
}
else {
throw new CommonException("用户绑定验证类型'" + authType.toString() + "'不支持");
}
}
if (bindUserInfo.getUserType() == 0) {
throw new CommonException("用户类型没有设置");
}
if (StringUtils.isBlank(bindUserInfo.getInfo())) {
throw new CommonException("绑定信息为空");
}
String bindId = userBindStoreService.save(source, session.getType(), session.getOpenId(), session.getUnionId(), bindUserInfo.getUserType(),
bindUserInfo.getInfo());
sessionMemoryService.invalid(source, sessionId);
session.setBindUser(true);
session.setBindId(bindId);
session.setUserType(bindUserInfo.getUserType());
session.setBindInfo(bindUserInfo.getInfo());
int sessionTimeout = 0;
if (session.getType() == AppType.MiniProgram) {
if (miniProgramConfigProperties == null) {
throw new CommonException("微信小程序配置信息为空");
}
sessionTimeout = miniProgramConfigProperties.getSessionTimeout();
}
else {
throw new CommonException("应用类型'" + session.getType().toString() + "'暂不支持");
}
sessionMemoryService.save(source, session, sessionTimeout);
}
@Override
public void unbind(String source, String sessionId) throws CommonException {
AbstractUserSession session = getSession(source, sessionId);
if (session == null) {
throw new CommonException("会话标识'" + sessionId + "'不存在");
}
if (!session.isBindUser()) {
throw new CommonException("用户未绑定");
}
userBindStoreService.delete(source, session.getType(), session.getOpenId());
sessionMemoryService.invalid(source, sessionId);
}
@Override
public void unbind(String source, AppType type, String openId) throws CommonException {
if (StringUtils.isBlank(source)) {
throw new CommonException("来源为空");
}
if (StringUtils.isBlank(openId)) {
throw new CommonException("微信标识Id为空");
}
userBindStoreService.delete(source, type, openId);
}
@Override
public boolean isOtherBind(String source, String sessionId) throws CommonException {
AbstractUserSession session = getSession(source, sessionId);
if (session.isBindUser()) {
return userBindStoreService.isOtherBind(source, session.getType(), session.getOpenId());
}
return false;
}
@Override
public AbstractUserSession getSession(String source, String sessionId) throws CommonException {
if (StringUtils.isBlank(source)) {
throw new CommonException("来源为空");
}
if (StringUtils.isBlank(sessionId)) {
throw new CommonException("会话标识为空");
}
Object sessionObj = sessionMemoryService.get(source, sessionId);
if (sessionObj == null) {
throw new CommonException(WeChatExceptionConstants.WECHAT_SESSION_INVALID, "会话'" + sessionId + "'已经失效");
}
return (AbstractUserSession) sessionObj;
}
@Override
public AbstractUserSession[] getSessions(String source) throws CommonException {
return sessionMemoryService.getAll(source);
}
@Override
public String getOpenId(String source, AppType type, int userType, String userInfo) throws CommonException {
if (StringUtils.isBlank(source)) {
throw new CommonException("来源为空");
}
if (userType == 0) {
throw new CommonException("用户类型没有设置");
}
if (StringUtils.isBlank(userInfo)) {
throw new CommonException("用户信息为空");
}
return userBindStoreService.getOpenId(source, type, userType, userInfo);
}
@Override
public UserBindInfo getUserBindInfo(String source, AppType type, String openId) throws CommonException {
if (StringUtils.isBlank(source)) {
throw new CommonException("来源为空");
}
if (type == AppType.OfficialAccounts) {
if (StringUtils.isBlank(openId)) {
throw new CommonException("微信公众号标识Id为空");
}
}
else if (type == AppType.MiniProgram) {
if (StringUtils.isBlank(openId)) {
throw new CommonException("微信小程序标识Id为空");
}
}
else {
throw new CommonException("应用类型'" + type.toString() + "'暂不支持");
}
return userBindStoreService.getUserBindInfo(source, type, openId, null);
}
@Override
public UserInfo getUserInfo(String source, String openId, String lang) throws CommonException {
if (StringUtils.isBlank(source)) {
throw new CommonException("来源为空");
}
if (StringUtils.isBlank(openId)) {
throw new CommonException("微信公众号标识Id为空");
}
String accessToken = weChatService.getAccessToken(AppType.OfficialAccounts, source);
if (StringUtils.isBlank(accessToken)) {
throw new CommonException("微信公众号访问令牌为空");
}
String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId + "&lang="
+ (StringUtils.isNotBlank(lang) ? lang : "zh_CN");
logger.debug("微信的获得用户信息请求地址:" + url);
JSONObject resultJson = restTemplateUtils.get(url, MediaType.APPLICATION_JSON, null, JSONObject.class);
logger.debug("微信的获得用户信息返回:" + resultJson.toString());
boolean isErrMsg = resultJson.containsKey("errmsg");
if (isErrMsg) {
throw new CommonException("微信的获得用户信息接口异常,错误码:" + resultJson.getString("errcode") + ",错误信息:" + resultJson.getString("errmsg"));
}
String rOpenId = resultJson.getString("openid");
if (!StringUtils.equals(rOpenId, openId)) {
throw new CommonException("微信的获得用户信息接口得到数据异常");
}
List tagIdList = null;
JSONArray tagIdListJson = resultJson.getJSONArray("tagid_list");
if (tagIdListJson != null && tagIdListJson.size() > 0) {
tagIdList = new Vector();
for (int i = 0; i < tagIdListJson.size(); i++) {
tagIdList.add(tagIdListJson.getLong(i));
}
}
Integer subscribe = resultJson.getInteger("subscribe");
if (subscribe == 1) {
return new UserInfo(resultJson.getString("nickname"), resultJson.getInteger("sex"), resultJson.getString("country"),
resultJson.getString("province"), resultJson.getString("city"), resultJson.getString("headimgurl"),
resultJson.getString("unionid"), resultJson.getLong("subscribe_time"), resultJson.getString("language"),
resultJson.getString("remark"), resultJson.getLong("groupid"), tagIdList, resultJson.getString("subscribe_scene"),
resultJson.getLong("qr_scene"), resultJson.getString("qr_scene_str"));
}
return null;
}
@Override
public void bindInit(String source, AppType type, String openId, String unionId) throws CommonException {
if (StringUtils.isBlank(source)) {
throw new CommonException("来源为空");
}
if (StringUtils.isBlank(openId)) {
throw new CommonException("微信标识Id为空");
}
if (StringUtils.isBlank(unionId)) {
throw new CommonException("微信唯一标识Id为空");
}
userBindStoreService.saveInit(source, type, openId, unionId);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy