Commit 126e6cc6 authored by hanfeng's avatar hanfeng

Merge remote-tracking branch 'origin/master_activity' into master_activity-hf

parents dd24691f c513f929
/**
* Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
package com.xxfc.platform.summit.model;
import java.io.Serializable;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
/**
* 封装 access_token
*/
@Data
public class AccessToken implements Serializable {
private static final long serialVersionUID = -822464425433824314L;
private String access_token; // 正确获取到 access_token 时有值
private Integer expires_in; // 正确获取到 access_token 时有值
private Long expiredTime; // 正确获取到 access_token 时有值,存放过期时间
private String json;
@SuppressWarnings("unchecked")
public AccessToken(String jsonStr) {
this.json = jsonStr;
try {
JSONObject temp =JSON.parseObject(jsonStr);
access_token = temp.getString("access_token");
expires_in = temp.getInteger("expires_in");
if (expires_in != null){
expiredTime = System.currentTimeMillis() + ((expires_in -5) * 1000);
System.out.println("----expiredTime==="+expiredTime);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public AccessToken(String json,String access_token,Integer expires_in) {
this.json = json;
this.access_token = access_token;
this.expires_in = expires_in;
if (expires_in != null)
expiredTime = System.currentTimeMillis() + ((expires_in -5) * 1000);
}
public String getJson() {
return json;
}
public boolean isAvailable() {
if (expiredTime < System.currentTimeMillis())
return false;
return access_token != null;
}
public void setJson(String json) {
this.json = json;
}
private Integer getInt(Map<String, Object> temp, String key) {
Number number = (Number) temp.get(key);
return number == null ? null : number.intValue();
}
}
package com.xxfc.platform.summit.model;
import java.io.Serializable;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* JsTicket返回封装
*/
public class JsTicket implements Serializable {
private static final long serialVersionUID = 6600179487477942329L;
private String ticket; // 正确获取到 ticket 时有值
private Integer expires_in; // 正确获取到 access_token 时有值
private Long expiredTime; // 正确获取到 ticket 时有值,存放过期时间
public JsTicket()
{
}
public JsTicket(String jsonStr) {
try {
JSONObject temp = JSON.parseObject(jsonStr);
ticket = temp.getString("ticket");
expires_in = temp.getInteger("expires_in");
if (expires_in != null)
expiredTime = System.currentTimeMillis() + ((expires_in - 5) * 1000);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Integer getInt(Map<String, Object> temp, String key) {
Number number = (Number) temp.get(key);
return number == null ? null : number.intValue();
}
public boolean isAvailable() {
if (expiredTime == null)
return false;
if (expiredTime < System.currentTimeMillis())
return false;
return ticket != null;
}
public String getTicket() {
return ticket;
}
public Integer getExpiresIn() {
return expires_in;
}
public Integer getExpires_in() {
return expires_in;
}
public void setExpires_in(Integer expires_in) {
this.expires_in = expires_in;
}
public Long getExpiredTime() {
return expiredTime;
}
public void setExpiredTime(Long expiredTime) {
this.expiredTime = expiredTime;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
}
package com.xxfc.platform.summit.util;
import java.security.MessageDigest;
public class Sha1 {
//Sha1签名
public static String getSha1(String str) {
if (str == null || str.length() == 0) {
return null;
}
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("GBK"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
}
......@@ -3,10 +3,13 @@ package com.xxfc.platform.summit.controller;
import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.summit.biz.ActivityBmBiz;
import com.xxfc.platform.summit.biz.UserBiz;
import com.xxfc.platform.summit.entity.ActivityBm;
import com.xxfc.platform.summit.entity.User;
import com.xxfc.platform.summit.service.WXjsService;
import com.xxfc.platform.summit.service.WeixinService;
import com.xxfc.platform.summit.vo.UserInfo;
import lombok.extern.slf4j.Slf4j;
......@@ -14,10 +17,8 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
......@@ -30,7 +31,6 @@ import javax.servlet.http.HttpSession;
public class WeixinController {
public static final String WECHAT_AUTOLOGIN_CALLBACKURL_KEY = "callback";
public static final String WECHAT_REDIS_KEY = "key";
@Autowired
WeixinService weixinService;
......@@ -41,7 +41,9 @@ public class WeixinController {
@Autowired
ActivityBmBiz activityBmBiz;
public static final String frontSessionKey = "frontWeixKey";
@Autowired
WXjsService wXjsService;
@Value("${wx.url}")
private String url;
......@@ -50,15 +52,16 @@ public class WeixinController {
@RequestMapping(value ="/app/unauth/wxLogin",method = RequestMethod.GET)
@IgnoreUserToken
public String index(@RequestParam(value = "redirec_url")String redirec_url,
@RequestParam(value = "key")String key){
log.info("-----微信wxLogin---redirec_url=="+redirec_url);
if (StringUtils.isBlank(redirec_url)){
public String index(@RequestParam(value = "redirec_url",defaultValue = "")String redirec_url,
@RequestParam(value = "key",defaultValue = "")String key){
log.info("-----微信wxLogin---redirec_url=="+redirec_url+"-----key===="+key);
if (StringUtils.isBlank(redirec_url)||StringUtils.isBlank(key)){
redirec_url="";
}
try {
String encrypt_curr_url = Base64.encode(redirec_url.getBytes("utf-8"));
redirec_url=url+"?" + WECHAT_AUTOLOGIN_CALLBACKURL_KEY+ "=" + encrypt_curr_url+"&"+WECHAT_REDIS_KEY+"="+key;
encrypt_curr_url+=","+key;
redirec_url=url+"?" + WECHAT_AUTOLOGIN_CALLBACKURL_KEY+ "=" + encrypt_curr_url;
String oauth_api=weixinService.getAuthorize(redirec_url);
return String.format("redirect:"+oauth_api);
}catch (Exception e){
......@@ -75,17 +78,39 @@ public class WeixinController {
* @return
*/
@GetMapping(value = "/app/unauth/userInfo")
public String getUserInformation(String code, String callback,String key, HttpServletRequest request) {
log.info("-----微信回调userInfo---code=="+code+"----redirec_url==="+callback+"---key==="+key);
public String getUserInformation(String code, String callback, HttpServletRequest request) {
log.info("-----微信回调userInfo---code=="+code+"----redirec_url==="+callback);
try {
String [] params=callback.split(",");
String key=params[1];
callback=params[0];
userBiz.authUser(code,key,request);
callback =new String(Base64.decode(callback), "utf-8");
log.info("callback===" + callback);
return String.format("redirect:"+callback);
}catch (Exception e){
e.printStackTrace();
log.info("网络异常===" + e.getMessage());
return String.format("网络异常");
}
return String.format("redirect:"+callback);
}
/**
* 微信分享
* @param url
* @return
*/
@GetMapping(value = "/app/unauth/share")
public @ResponseBody ObjectRestResponse share(@RequestParam("url") String url) {
log.info("-----微信分享share---url=="+url);
try {
return ObjectRestResponse.succ(wXjsService.getShareData(url));
}catch (Exception e){
e.printStackTrace();
return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE,"网络异常");
}
}
......
......@@ -59,15 +59,17 @@ public class WeChatH5LoginInterceptor extends HandlerInterceptorAdapter {
return true;
}
String redisKey=redisInfo(request);
Map<String,Object> result=new HashMap<>();
JSONObject result=new JSONObject();
JSONObject json = new JSONObject();
if (StringUtils.isNotBlank(redisKey)){
json.put("key",redisKey);
}
json.put("url","https://dev.dfangche.com/api/summit/auth/app/unauth/wxLogin?redirec_url=https://dev.dfangche.com/h5/appHtml/view/wxh5/index.html");
json.put("url","https://dev.dfangche.com/api/summit/auth/app/unauth/wxLogin");
result.put("data",json);
result.put("status",1001);
response.getWriter().write(result.toString());
response.setCharacterEncoding("utf-8");
response.setContentType("application/json; charset=utf-8");
response.getWriter().append(result.toString());
return false;
}
return true;
......@@ -87,15 +89,17 @@ public class WeChatH5LoginInterceptor extends HandlerInterceptorAdapter {
{
e.printStackTrace();
}
String redisLockKey=null;
String key=null;
if (StringUtils.isNotBlank(jb)){
redisLockKey= RedisKey.CONSTANT_CODE_PREFIX + UUID.randomUUID();
Boolean suc = summbitRedisTemplate.opsForValue().setIfAbsent(redisLockKey, jb);
key= UUID.randomUUID()+"";
String redisLockKey= RedisKey.CONSTANT_CODE_PREFIX +key;
log.info("-----jb====="+jb.toString());
Boolean suc = summbitRedisTemplate.opsForValue().setIfAbsent(redisLockKey, jb.toString());
if (suc) {
summbitRedisTemplate.expire(redisLockKey, 5, TimeUnit.MINUTES);//5分钟内过期
}
}
return redisLockKey;
return key;
}
......
package com.xxfc.platform.summit.service;
import com.xxfc.platform.summit.model.AccessToken;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xxfc.platform.summit.util.HttpRequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* 认证并获取 access_token API
* http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token
*
* AccessToken默认存储于内存中,可设置存储于redis或者实现IAccessTokenCache到数据库中实现分布式可用
*
* 具体配置:
* <pre>
* ApiConfigKit.setAccessTokenCache(new RedisAccessTokenCache());
* </pre>
*/
@Service
@Slf4j
public class AccessTokenService {
@Autowired
private RedisTemplate summbitRedisTemplate;
// "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
private static String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
//"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
@Value("${wx.appid}")
private String wy_appid;
@Value("${wx.appSercet}")
private String wy_secret;
/**
* 从缓存中获取 access token,如果未取到或者 access token 不可用则先更新再获取
*/
public AccessToken getAccessToken() {
//从缓存中读取出accessToken
//RedisUtil redisUtil = new RedisUtil(ConstantConfig.REDIS_IP,ConstantConfig.REDIS_PORT);
//创建一个jedis的对象。
String accessTokenRedis = summbitRedisTemplate.opsForValue().get(wy_appid) == null ? "" : summbitRedisTemplate.opsForValue().get(wy_appid).toString();
log.info("---accessTokenRedis===="+accessTokenRedis);
if (StringUtils.isNotBlank(accessTokenRedis))
{
JSONObject obj = JSONObject.parseObject(accessTokenRedis).getJSONObject(wy_appid);
AccessToken accessToken = new AccessToken(obj.getString("json"),obj.getString("accessToken"),obj.getInteger("expiresIn"));
if(accessToken.isAvailable()){
return accessToken;
}
summbitRedisTemplate.delete(wy_appid);
}
refreshAccessToken();
accessTokenRedis = summbitRedisTemplate.opsForValue().get(wy_appid) == null ? "" : summbitRedisTemplate.opsForValue().get(wy_appid).toString();
JSONObject obj = JSONObject.parseObject(accessTokenRedis).getJSONObject(wy_appid);
AccessToken accessToken = new AccessToken(obj.getString("json"),obj.getString("accessToken"),obj.getInteger("expiresIn"));
return accessToken;
//return (AccessToken) ehcache.get(SystemConfig.WINXIN_AppID).getObjectValue();
}
private AccessToken AccessToken(String string, String string2,
Integer integer) {
// TODO Auto-generated method stub
return null;
}
/**
* 直接获取 accessToken 字符串,方便使用
* @return String accessToken
*/
public String getAccessTokenStr() {
return getAccessToken().getAccessToken();
}
/**
* 强制更新 access token 值
*/
public void refreshAccessToken() {
//RedisUtil redisUtil = new RedisUtil(ConstantConfig.REDIS_IP,ConstantConfig.REDIS_PORT);
AccessToken result = null;
for (int i=0; i<3; i++) { // 最多三次请求
String json = HttpRequestUtil.httpGet(url+"&appid="+wy_appid+"&secret="+wy_secret);
log.info("---json===="+json);
result = new AccessToken(json);
log.info("---result===="+result.toString());
if (result.isAvailable())
break;
}
// 三次请求如果仍然返回了不可用的 access token 仍然 put 进去,便于上层通过 AccessToken 中的属性判断底层的情况
JSONObject obj = new JSONObject();
obj.put(wy_appid, result);
Boolean suc=summbitRedisTemplate.opsForValue().setIfAbsent(wy_appid, obj.toJSONString());
if (suc) {
summbitRedisTemplate.expire(wy_appid, result.getExpiresIn(), TimeUnit.MINUTES);
}
}
}
\ No newline at end of file
package com.xxfc.platform.summit.service;
import com.xxfc.platform.summit.model.JsTicket;
import com.xxfc.platform.summit.util.HttpRequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import java.util.concurrent.TimeUnit;
/**
*
* 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据
* https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
*
* 微信卡券接口签名凭证api_ticket
* https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card
*/
@Service
@Slf4j
public class JsTicketService {
@Autowired
private RedisTemplate summbitRedisTemplate;
@Autowired
AccessTokenService tokenService;
private static String apiUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?";
@Value("${wx.appid}")
private String wy_appid;
@Value("${wx.appSercet}")
private String wy_secret;
/**
* JSApi的类型
*
* jsapi: 用于分享等js-api
*
* wx_card:用于卡券接口签名凭证api_ticket
*
*/
public enum JsApiType {
jsapi, wx_card
}
/**
*
* http GET请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket)
*
* @param jsApiType
* @return JsTicket
*/
@SuppressWarnings("null")
public JsTicket getTicket(JsApiType jsApiType) {
String key = wy_appid + ':' + jsApiType.name();
//从缓存中取出来
//RedisUtil redisUtil = new RedisUtil(ConstantConfig.REDIS_IP,ConstantConfig.REDIS_PORT);
JsTicket jsTicket = new JsTicket();
String jsTicketRedis = summbitRedisTemplate.opsForValue().get(key) == null ? "" : summbitRedisTemplate.opsForValue().get(key).toString();
log.info("---jsTicketRedis===="+jsTicketRedis);
if (StringUtils.isNotBlank(jsTicketRedis))
{
JSONObject objTemp = new JSONObject();
objTemp = JSONObject.parseObject(jsTicketRedis).getJSONObject(key);
jsTicket.setExpiredTime(objTemp.getLong("expiredTime"));
jsTicket.setTicket(objTemp.getString("ticket"));
jsTicket.setExpires_in(objTemp.getInteger("expiresIn"));
// jsTicket = JSON.parseObject(redisUtil.get(key), JsTicket.class);
//(JsTicket) JSON.parseObject(redisUtil.get(key)).get(key);
if(!jsTicket.isAvailable())
{
log.info("---jsTicket----失效");
// https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card
String json = HttpRequestUtil.httpGet(apiUrl+"access_token="+ tokenService.getAccessTokenStr()+"&type="+jsApiType.name());
log.info("---json===="+json);
jsTicket = new JsTicket(json);
/*Element element = new Element(SystemConfig.WINXIN_AppID, jsTicket);
ehcache.put(element);*/
JSONObject obj = new JSONObject();
summbitRedisTemplate.delete(key);
Boolean suc=summbitRedisTemplate.opsForValue().setIfAbsent(key, obj.toJSONString());
if (suc) {
summbitRedisTemplate.expire(wy_appid, jsTicket.getExpiresIn(), TimeUnit.MINUTES);
}
}
}else{
String json = HttpRequestUtil.httpGet(apiUrl+"access_token="+ tokenService.getAccessTokenStr()+"&type="+jsApiType.name());
log.info("---json===="+json);
jsTicket = new JsTicket(json);
/*Element element = new Element(SystemConfig.WINXIN_AppID, jsTicket);
ehcache.put(element);*/
JSONObject obj = new JSONObject();
obj.put(key, jsTicket);
Boolean suc=summbitRedisTemplate.opsForValue().setIfAbsent(key, obj.toJSONString());
if (suc) {
summbitRedisTemplate.expire(wy_appid, jsTicket.getExpiresIn(), TimeUnit.MINUTES);
}
}
return jsTicket;
}
}
\ No newline at end of file
package com.xxfc.platform.summit.service;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import com.xxfc.platform.summit.util.Sha1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import java.util.Map.Entry;
@Service
public class WXjsService {
@Autowired
JsTicketService jsTicketService;
/**
* 生成js 微信调用配置参数
* @param _wxShareUrl:回掉的地址
* @return
*/
public JSONObject getShareData(String _wxShareUrl)
{
JSONObject data = new JSONObject();
Map<String, String> _wxMap = new TreeMap<String, String>();
//noncestr
String _wxNoncestr = UUID.randomUUID().toString().replace("-", "");
String _wxTimestamp = (System.currentTimeMillis() / 1000) + "";
String _wxJsapiTicket = jsTicketService.getTicket(JsTicketService.JsApiType.jsapi).getTicket();
//参数封装
_wxMap.put("noncestr", _wxNoncestr);
_wxMap.put("timestamp", _wxTimestamp );
_wxMap.put("jsapi_ticket", _wxJsapiTicket);
_wxMap.put("url", _wxShareUrl);
data.put("noncestr", _wxNoncestr);
data.put("timestamp", _wxTimestamp );
data.put("jsapi_ticket", _wxJsapiTicket);
data.put("url", _wxShareUrl);
// 加密获取signature
StringBuilder _wxBaseString = new StringBuilder();
for (Entry<String, String> param : _wxMap.entrySet()) {
_wxBaseString.append(param.getKey()).append("=").append(param.getValue()).append("&");
}
String _wxSignString = _wxBaseString.substring(0, _wxBaseString.length() - 1);
data.put("sign", Sha1.getSha1(_wxSignString));
return data;
}
}
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