Commit 8bdc4b7b authored by zhouqian's avatar zhouqian

log

parent 1fd43fad
package cn.quantgroup.xyqb.controller.external.user; package cn.quantgroup.xyqb.controller.external.user;
import cn.quantgroup.xyqb.entity.WebChatUserInfo; import cn.quantgroup.xyqb.entity.Merchant;
import cn.quantgroup.xyqb.entity.WechatUserInfo;
import cn.quantgroup.xyqb.model.JsonResult; import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.webchat.AccessTokenResponse; import cn.quantgroup.xyqb.model.webchat.AccessTokenResponse;
import cn.quantgroup.xyqb.service.http.IHttpService; import cn.quantgroup.xyqb.service.http.IHttpService;
import cn.quantgroup.xyqb.service.merchant.IMerchantService;
import cn.quantgroup.xyqb.service.user.IUserService; import cn.quantgroup.xyqb.service.user.IUserService;
import com.alibaba.fastjson.JSON; import cn.quantgroup.xyqb.service.wechat.IWechatService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
...@@ -26,26 +31,30 @@ import java.util.Arrays; ...@@ -26,26 +31,30 @@ import java.util.Arrays;
public class WeChatController { public class WeChatController {
// todo: 配置文件 // todo: 配置文件
public static final String TOKEN = "5YihkluEo5QuWAWpFwzvA"; private static final String TOKEN = "5YihkluEo5QuWAWpFwzvA";
@Autowired @Autowired
private IHttpService httpService; private IWechatService wechatService;
@Autowired @Autowired
private IUserService userService; private IMerchantService merchantService;
//todo: 配置文件相关
private String access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxcdf6077af8127559&secret=16eaec16084d0d9c52d4114f359cc72c&code=%s&grant_type=authorization_code"; // https://passport.xyqb.com/landing?key=xxx&target=cashTarget5&registerFrom=198&channelId=%d
private String access_userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN"; @Value("${xyqb-user.ui}")
private String userUIAddr;
/** /**
* 开发者资质认证,有必要吗? * 开发者资质认证,有必要吗?
*
* @param request * @param request
* @return * @return
*/ */
@RequestMapping("/checkValid") @RequestMapping("/checkValid")
public String valid(HttpServletRequest request) { public String valid(HttpServletRequest request) {
String echoStr = request.getParameter("echostr"); String echoStr = request.getParameter("echostr");
if(checkSignature(request)){ if (checkSignature(request)) {
return echoStr; return echoStr;
} }
return ""; return "";
...@@ -53,6 +62,7 @@ public class WeChatController { ...@@ -53,6 +62,7 @@ public class WeChatController {
/** /**
* 微信登录 * 微信登录
*
* @param name 姓名 * @param name 姓名
* @param idNo 身份证号 * @param idNo 身份证号
* @param phoneNo 手机号 * @param phoneNo 手机号
...@@ -63,11 +73,11 @@ public class WeChatController { ...@@ -63,11 +73,11 @@ public class WeChatController {
* @return * @return
*/ */
public JsonResult webChatLogin(String name, String idNo, String phoneNo, String registerFrom, public JsonResult webChatLogin(String name, String idNo, String phoneNo, String registerFrom,
String channelId, String appChannel, String key){ String channelId, String appChannel, String key) {
if(StringUtils.isBlank(name) || StringUtils.isBlank(idNo) || StringUtils.isBlank(phoneNo)){ if (StringUtils.isBlank(name) || StringUtils.isBlank(idNo) || StringUtils.isBlank(phoneNo)) {
return JsonResult.buildErrorStateResult("请填写完整的用户信息.", null); return JsonResult.buildErrorStateResult("请填写完整的用户信息.", null);
} }
if(StringUtils.isBlank(key)){ if (StringUtils.isBlank(key)) {
return JsonResult.buildErrorStateResult("无效的商户信息.", null); return JsonResult.buildErrorStateResult("无效的商户信息.", null);
} }
return null; return null;
...@@ -80,6 +90,7 @@ public class WeChatController { ...@@ -80,6 +90,7 @@ public class WeChatController {
* 2.用timestamp, nonce, token三个参数做字符升序排列 * 2.用timestamp, nonce, token三个参数做字符升序排列
* 3.将排列好的字符串进行sha1加密,和signature参数做比较 * 3.将排列好的字符串进行sha1加密,和signature参数做比较
* 4.相等返回true,否则返回false * 4.相等返回true,否则返回false
*
* @param request * @param request
* @return * @return
*/ */
...@@ -97,6 +108,7 @@ public class WeChatController { ...@@ -97,6 +108,7 @@ public class WeChatController {
/** /**
* sha1加密算法, * sha1加密算法,
*
* @param decript * @param decript
* @return 返回40位16进制字符串 * @return 返回40位16进制字符串
*/ */
...@@ -125,12 +137,13 @@ public class WeChatController { ...@@ -125,12 +137,13 @@ public class WeChatController {
/** /**
* 数组分割为字符串 * 数组分割为字符串
*
* @param arr * @param arr
* @return * @return
*/ */
private String joinArray(String[] arr) { private String joinArray(String[] arr) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for(String str : arr){ for (String str : arr) {
builder.append(str); builder.append(str);
} }
return builder.toString(); return builder.toString();
...@@ -138,47 +151,50 @@ public class WeChatController { ...@@ -138,47 +151,50 @@ public class WeChatController {
/** /**
* 通过redirect_url获取code * 通过redirect_url获取code
* @param request *
* @param response
* @return * @return
*/ */
@RequestMapping("/receiveCode") @RequestMapping("/receiveCode/{key}")
public String receiveCode(HttpServletRequest request) { public void receiveCode(String code, @PathVariable(value = "key") String systemKey, HttpServletResponse response) {
String code = request.getParameter("code"); // 从code获取token
receiveAccessToken(code); Merchant merchant = merchantService.findMerchantByName(systemKey);
return null;
AccessTokenResponse token = wechatService.getToken(code);
if (token == null) {
// todo: 让用户登录,不关联微信, 构造不关联微信的url
response.setHeader("Location", redirectUrl);
response.setStatus(301);
return;
}
WechatUserInfo userInfo = wechatService.getWechatUserInfoFromWechatServer(token.getAccessToken(), token.getOpenId());
if (userInfo == null) {
// todo: 让用户登录,不关联微信, 构造不关联微信的url
response.setHeader("Location", redirectUrl);
response.setStatus(301);
return;
}
WechatUserInfo userInfoInDb = wechatService.findWechatUserInfoFromDb(userInfo.getOpenId());
// welcome 首次登录
if (userInfoInDb == null) {
// todo: 微信用户首次登录界面, 首先保存userInfo, 跳入到微信注册登录界面
userInfo = wechatService.saveWechatUserInfo(userInfo);
response.setHeader("Location", redirectUrl);
response.setStatus(301);
return;
}
if (userInfoInDb.getUserId() == null) {
// todo: 用户已经微信登录了,但是没有关联信用钱包,跳转到注册页面
response.setHeader("Location", redirectUrl);
response.setStatus(301);
return;
}
// 已经关联了用户
// todo: create session, 登进去,该怎么玩怎么玩。
createUserSession(userInfo, merchant);
response.setHeader("Location", redirectUrl);
response.setStatus(301);
} }
/**
* 拿到access_token,openId,获取用户信息,入库
* @param code
* @return
*/
private JsonResult receiveAccessToken(String code) {
String finalAccessTokenUrl = String.format(access_token_url, code);
String response = httpService.get(finalAccessTokenUrl);
AccessTokenResponse accessTokenResponse = null;
try {
accessTokenResponse = JSON.parseObject(response, AccessTokenResponse.class);
} catch (Exception e){
log.error("获取access_token出错{}:", e);
return JsonResult.buildErrorStateResult("获取access_token出错", null);
}
//从AccessTokenResponse中获取access_token, openid
String access_token = accessTokenResponse.getAccessToken();
String openId = accessTokenResponse.getOpenId();
String finalUserInfoUrl = String.format(access_userinfo_url, access_token, openId);
//拉取用户信息
String userInfo = httpService.get(finalUserInfoUrl);
saveWebChatUserInfo(userInfo);
return JsonResult.buildSuccessResult("success", null);
}
/**
* 保存微信用户信息
* @param userInfo
*/
private void saveWebChatUserInfo(String userInfo) {
WebChatUserInfo webChatUserInfo = JSON.parseObject(userInfo, WebChatUserInfo.class);
userService.saveWebChatUserInfo(webChatUserInfo);
}
} }
...@@ -13,9 +13,9 @@ import java.io.Serializable; ...@@ -13,9 +13,9 @@ import java.io.Serializable;
* 微信关联的用户信息 * 微信关联的用户信息
*/ */
@Entity @Entity
@Table(name = "webchat_userinfo") @Table(name = "wechat_userinfo")
@Data @Data
public class WebChatUserInfo implements Serializable{ public class WechatUserInfo implements Serializable{
private static final long serialVersionUID = -1L; private static final long serialVersionUID = -1L;
@Id @Id
......
...@@ -16,4 +16,6 @@ public class AccessTokenResponse implements Serializable{ ...@@ -16,4 +16,6 @@ public class AccessTokenResponse implements Serializable{
private String refreshToken; private String refreshToken;
private String openId; private String openId;
private String scope; private String scope;
private Long initialTime;
} }
package cn.quantgroup.xyqb.repository; package cn.quantgroup.xyqb.repository;
import cn.quantgroup.xyqb.entity.WebChatUserInfo; import cn.quantgroup.xyqb.entity.WechatUserInfo;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
/** /**
* Created by 11 on 2017/1/18. * Created by 11 on 2017/1/18.
*/ */
public interface IWebChatUserRepository extends JpaRepository<WebChatUserInfo, Long> { public interface IWeChatUserRepository extends JpaRepository<WechatUserInfo, Long> {
WechatUserInfo findByOpenId(String openId);
} }
package cn.quantgroup.xyqb.service.user; package cn.quantgroup.xyqb.service.user;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.WebChatUserInfo; import cn.quantgroup.xyqb.entity.WechatUserInfo;
/** /**
* Created by Miraculous on 15/7/5. * Created by Miraculous on 15/7/5.
...@@ -28,5 +28,4 @@ public interface IUserService { ...@@ -28,5 +28,4 @@ public interface IUserService {
User findById(Long userId); User findById(Long userId);
WebChatUserInfo saveWebChatUserInfo(WebChatUserInfo webChatUserInfo);
} }
...@@ -2,9 +2,7 @@ package cn.quantgroup.xyqb.service.user.impl; ...@@ -2,9 +2,7 @@ package cn.quantgroup.xyqb.service.user.impl;
import cn.quantgroup.xyqb.Constants; import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.WebChatUserInfo;
import cn.quantgroup.xyqb.repository.IUserRepository; import cn.quantgroup.xyqb.repository.IUserRepository;
import cn.quantgroup.xyqb.repository.IWebChatUserRepository;
import cn.quantgroup.xyqb.service.sms.ISmsService; import cn.quantgroup.xyqb.service.sms.ISmsService;
import cn.quantgroup.xyqb.service.user.ILkbUserService; import cn.quantgroup.xyqb.service.user.ILkbUserService;
import cn.quantgroup.xyqb.service.user.IUserService; import cn.quantgroup.xyqb.service.user.IUserService;
...@@ -38,9 +36,6 @@ public class UserServiceImpl implements IUserService { ...@@ -38,9 +36,6 @@ public class UserServiceImpl implements IUserService {
@Autowired @Autowired
private ISmsService smsService; private ISmsService smsService;
@Autowired
private IWebChatUserRepository webChatUserRepository;
@Override @Override
public User findByPhoneInDb(String phone) { public User findByPhoneInDb(String phone) {
return userRepository.findByPhoneNo(phone); return userRepository.findByPhoneNo(phone);
...@@ -61,10 +56,6 @@ public class UserServiceImpl implements IUserService { ...@@ -61,10 +56,6 @@ public class UserServiceImpl implements IUserService {
return userRepository.findById(userId); return userRepository.findById(userId);
} }
@Override
public WebChatUserInfo saveWebChatUserInfo(WebChatUserInfo webChatUserInfo) {
return webChatUserRepository.save(webChatUserInfo);
}
@Override @Override
public User registerAndReturn(String phoneNo, String password, Long registerFrom) { public User registerAndReturn(String phoneNo, String password, Long registerFrom) {
......
package cn.quantgroup.xyqb.service.wechat;
import cn.quantgroup.xyqb.entity.WechatUserInfo;
import cn.quantgroup.xyqb.model.webchat.AccessTokenResponse;
/**
* Created by Miraculous on 2017/1/19.
*/
public interface IWechatService {
AccessTokenResponse getToken(String code);
WechatUserInfo getWechatUserInfoFromWechatServer(String token, String openId);
WechatUserInfo findWechatUserInfoFromDb(String openId);
WechatUserInfo saveWechatUserInfo(WechatUserInfo userInfo);
}
package cn.quantgroup.xyqb.service.wechat.impl;
import cn.quantgroup.cloudconfig.SafeValue;
import cn.quantgroup.xyqb.entity.WechatUserInfo;
import cn.quantgroup.xyqb.model.webchat.AccessTokenResponse;
import cn.quantgroup.xyqb.repository.IWeChatUserRepository;
import cn.quantgroup.xyqb.service.http.IHttpService;
import cn.quantgroup.xyqb.service.wechat.IWechatService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;
/**
* Created by Miraculous on 2017/1/19.
*/
@Service
public class WechatServiceImpl implements IWechatService {
@Autowired
private IHttpService httpService;
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
@SafeValue("wechat.appid")
private String appId;
@SafeValue("wechat.secret")
private String secret;
@Autowired
private IWeChatUserRepository weChatUserRepository;
private String accessTokenUrl;
private String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s";
private static final String WECHAT_TOKEN_KEY_PREFIX = "wechat:token:";
@PostConstruct
private void init() {
accessTokenUrl = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&grant_type=authorization_code&code=", appId, secret) + "%s";
refreshTokenUrl = String.format("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=", appId) + "%s";
}
@Override
public AccessTokenResponse getToken(String code) {
if (StringUtils.isEmpty(code)) {
return null;
}
String key = WECHAT_TOKEN_KEY_PREFIX + code;
String resultStr = redisTemplate.opsForValue().get(key);
if (StringUtils.isEmpty(resultStr)) {
String response = getTokenFromWechatServer(code);
if (StringUtils.isEmpty(response)) {
return null;
}
try {
AccessTokenResponse accessTokenResponse = JSONObject.parseObject(response,
AccessTokenResponse.class);
if (accessTokenResponse == null) {
return null;
}
accessTokenResponse.setInitialTime(System.currentTimeMillis() - 10000);
redisTemplate.opsForValue().set(key, JSONObject.toJSONString(accessTokenResponse), accessTokenResponse.getExpiresIn() + 1000, TimeUnit.SECONDS);
return accessTokenResponse;
} catch (Exception ex) {
return null;
}
} else {
try {
AccessTokenResponse response = JSONObject.parseObject(resultStr, AccessTokenResponse.class);
// 刷新
if (response.getInitialTime() + response.getExpiresIn()*1000 > System.currentTimeMillis()) {
String refreshTokenStr = refreshToken(response.getRefreshToken());
response = JSONObject.parseObject(refreshTokenStr, AccessTokenResponse.class);
if (response == null) {
return null;
}
response.setInitialTime(System.currentTimeMillis() - 10000);
}
redisTemplate.opsForValue().set(key, JSONObject.toJSONString(response), response.getExpiresIn() + 1000, TimeUnit.SECONDS);
return response;
} catch (Exception ex) {
return null;
}
}
}
@Override
public WechatUserInfo getWechatUserInfoFromWechatServer(String token, String openId) {
if (StringUtils.isEmpty(token) || StringUtils.isEmpty(openId)) {
return null;
}
String accessUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";
String url = String.format(accessUserInfoUrl, token, openId);
String result = httpService.get(url);
return JSONObject.parseObject(result, WechatUserInfo.class);
}
@Override
public WechatUserInfo findWechatUserInfoFromDb(String openId) {
return weChatUserRepository.findByOpenId(openId);
}
@Override
@Transactional
public WechatUserInfo saveWechatUserInfo(WechatUserInfo userInfo) {
return weChatUserRepository.save(userInfo);
}
private String getTokenFromWechatServer(String code) {
if (StringUtils.isEmpty(code)) {
return null;
}
String finalAccessTokenUrl = String.format(accessTokenUrl, code);
return httpService.get(finalAccessTokenUrl);
}
private String refreshToken(String refreshToken) {
if (StringUtils.isEmpty(refreshToken)) {
return null;
}
return httpService.get(String.format(refreshTokenUrl, refreshToken));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment