java微信公众号网页开发平台_Java微信公众平台开发_05_微信网页授权

packagecom.ray.weixin.gz.util;importjava.io.UnsupportedEncodingException;importjava.net.URLDecoder;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Arrays;importjava.util.Formatter;importjava.util.UUID;importjavax.servlet.http.HttpServletRequest;importorg.apache.logging.log4j.LogManager;importorg.apache.logging.log4j.Logger;importcom.alibaba.fastjson.JSONObject;importcom.ray.weixin.gz.config.Env;importcom.ray.weixin.gz.service.invoice.InvoiceService;/*** 微信公众号 Token、配置工具类

* @desc : AccessToken、Jsticket 、Jsapi

*

*@author: shirayner

* @date : 2017年9月27日 下午5:00:25*/

public classAuthHelper {private static final Logger logger = LogManager.getLogger(AuthHelper.class);//1.获取access_token的接口地址,有效期为7200秒

private static final String GET_ACCESSTOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";//2.获取getJsapiTicket的接口地址,有效期为7200秒

private static final String GET_JSAPITICKET_URL="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";//3.通过code换取网页授权access_token

private static final String GET_ACCESSTOKEN_BYCODE_URL="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";/*** @desc :1.获取access_token

*

*@paramappId 第三方用户唯一凭证

*@paramappSecret 第三方用户唯一凭证密钥,即appsecret

*

*@return* access_token 获取到的凭证

* expires_in 凭证有效时间,单位:秒

*@throwsException String*/

public static String getAccessToken(String appId,String appSecret) throwsException {//1.获取请求url

String url=GET_ACCESSTOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecret);//2.发起GET请求,获取返回结果

JSONObject jsonObject=HttpHelper.doGet(url);

logger.info("jsonObject:"+jsonObject.toJSONString());//3.解析结果,获取accessToken

String accessToken="";if (null !=jsonObject) {//4.错误消息处理

if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {int errCode = jsonObject.getInteger("errcode");

String errMsg= jsonObject.getString("errmsg");throw new Exception("error code:"+errCode+", error message:"+errMsg);//5.成功获取accessToken

}else{

accessToken=jsonObject.getString("access_token");

}

}returnaccessToken;

}/*** @desc :2.获取JsapiTicket

*

*@paramaccessToken 有效凭证

*@return*@throwsException String*/

public static String getJsapiTicket(String accessToken) throwsException {//1.获取请求url

String url=GET_JSAPITICKET_URL.replace("ACCESS_TOKEN", accessToken);//2.发起GET请求,获取返回结果

JSONObject jsonObject=HttpHelper.doGet(url);

logger.info("jsonObject:"+jsonObject.toJSONString());//3.解析结果,获取accessToken

String jsapiTicket="";if (null !=jsonObject) {//4.错误消息处理

if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {int errCode = jsonObject.getInteger("errcode");

String errMsg= jsonObject.getString("errmsg");throw new Exception("error code:"+errCode+", error message:"+errMsg);//5.成功获取jsapiTicket

}else{

jsapiTicket=jsonObject.getString("ticket");

}

}returnjsapiTicket;

}/*** @desc : 3.通过code换取网页授权access_token

*

*@paramappId 第三方用户唯一凭证

*@paramappSecret 第三方用户唯一凭证密钥,即appsecret

*@paramCode code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

*

*@return* access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同

* expires_in access_token接口调用凭证超时时间,单位(秒)

* refresh_token 用户刷新access_token

* openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID

* scope 用户授权的作用域,使用逗号(,)分隔

*

*@throwsException String*/

public static JSONObject getAccessTokenByCode(String appId,String appSecret,String code) throwsException {//1.获取请求url

String url=GET_ACCESSTOKEN_BYCODE_URL.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);//2.发起GET请求,获取返回结果

JSONObject jsonObject=HttpHelper.doGet(url);

logger.info("jsonObject:"+jsonObject.toJSONString());//3.解析结果,获取accessToken

JSONObject returnJsonObject=null;if (null !=jsonObject) {//4.错误消息处理

if (jsonObject.getInteger("errcode")!=null && 0 != jsonObject.getInteger("errcode")) {int errCode = jsonObject.getInteger("errcode");

String errMsg= jsonObject.getString("errmsg");throw new Exception("error code:"+errCode+", error message:"+errMsg);//5.成功获取accessToken

}else{

returnJsonObject=jsonObject;

}

}returnreturnJsonObject;

}/*** @desc :4.获取前端jsapi需要的配置参数

*

*@paramrequest

*@returnString*/

public staticString getJsapiConfig(HttpServletRequest request){//1.准备好参与签名的字段//1.1 url

/**以http://localhost/test.do?a=b&c=d为例

*request.getRequestURL的结果是http://localhost/test.do

*request.getQueryString的返回值是a=b&c=d*/String urlString=request.getRequestURL().toString();

String queryString=request.getQueryString();

String queryStringEncode= null;

String url;if (queryString != null) {

queryStringEncode=URLDecoder.decode(queryString);

url= urlString + "?" +queryStringEncode;

}else{

url=urlString;

}//1.2 noncestr

String nonceStr=UUID.randomUUID().toString(); //随机数//1.3 timestamp

long timeStamp = System.currentTimeMillis() / 1000; //时间戳参数

String signedUrl=url;

String accessToken= null;

String ticket= null;

String signature= null; //签名

try{//1.4 jsapi_ticket

accessToken=getAccessToken(Env.APP_ID, Env.APP_SECRET);

ticket=getJsapiTicket(accessToken);//2.进行签名,获取signature

signature=getSign(ticket,nonceStr,timeStamp,signedUrl);

}catch(Exception e) {//TODO Auto-generated catch block

e.printStackTrace();

}

logger.info("accessToken:"+accessToken);

logger.info("ticket:"+ticket);

logger.info("nonceStr:"+nonceStr);

logger.info("timeStamp:"+timeStamp);

logger.info("signedUrl:"+signedUrl);

logger.info("signature:"+signature);

logger.info("appId:"+Env.APP_ID);

String configValue= "{signature:'" + signature + "',nonceStr:'" + nonceStr + "',timeStamp:'"

+ timeStamp + "',appId:'" + Env.APP_ID + "'}";

logger.info("configValue:"+configValue);returnconfigValue;

}/*** @desc : 4.1 生成签名的函数

*

*@paramticket jsticket

*@paramnonceStr 随机串,自己定义

*@paramtimeStamp 生成签名用的时间戳

*@paramurl 需要进行免登鉴权的页面地址,也就是执行dd.config的页面地址

*@return*@throwsException String*/

public static String getSign(String jsTicket, String nonceStr, Long timeStamp, String url) throwsException {

String plainTex= "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "&timestamp=" + timeStamp + "&url=" +url;

System.out.println(plainTex);try{

MessageDigest crypt= MessageDigest.getInstance("SHA-1");

crypt.reset();

crypt.update(plainTex.getBytes("UTF-8"));returnbyteToHex(crypt.digest());

}catch(NoSuchAlgorithmException e) {throw newException(e.getMessage());

}catch(UnsupportedEncodingException e) {throw newException(e.getMessage());

}

}/*** @desc :4.2 将bytes类型的数据转化为16进制类型

*

*@paramhash

*@return* String*/

private static String byteToHex(byte[] hash) {

Formatter formatter= newFormatter();for (byteb : hash) {

formatter.format("%02x", newObject[] { Byte.valueOf(b) });

}

String result=formatter.toString();

formatter.close();returnresult;

}/**5.获取前端所需发票签名参数

*

* @desc :

*(1)将 api_ticket、appid、timestamp、nonceStr、cardType的value值进行字符串的字典序排序。

*(2)再将所有参数字符串拼接成一个字符串进行sha1加密,得到cardSign。

*

*@returnString

* timestamp :卡券签名时间戳

nonceStr : 卡券签名随机串

signType : 签名方式,默认'SHA1'

cardSign : 卡券签名

**/

public staticString getInvoiceConfig(){//1.准备好签名参数//1.1 api_ticket 授权页ticket

String apiTicket=null;try{

String accessToken=AuthHelper.getAccessToken(Env.APP_ID, Env.APP_SECRET);

apiTicket=InvoiceService.getAuthPageTicket(accessToken);

}catch(Exception e) {

logger.info("获取授权页ticket失败");

e.printStackTrace();

}//1.2 appid

String appId=Env.APP_ID;//1.3 timestamp 时间戳

String timeStamp = System.currentTimeMillis() / 1000 +"";//1.4 nonceStr 随机数

String nonceStr=UUID.randomUUID().toString();//1.5 cardType

String cardType="INVOICE";//2.获取签名

String cardSign=null;try{

cardSign=AuthHelper.getCardSign(apiTicket, appId, timeStamp, nonceStr, cardType);

}catch(Exception e) {

logger.info("获取发票签名失败");

e.printStackTrace();

}

String signType="SHA1";

logger.info("apiTicket:"+apiTicket);

logger.info("appId:"+appId);

logger.info("timeStamp:"+timeStamp);

logger.info("nonceStr:"+nonceStr);

logger.info("cardType:"+cardType);

logger.info("cardSign:"+cardSign);

logger.info("signType:"+signType);//3.返回前端所需发票签名参数

JSONObject jsonObject=newJSONObject();

jsonObject.put("timestamp", timeStamp);

jsonObject.put("nonceStr",nonceStr );

jsonObject.put("signType",signType );

jsonObject.put("cardSign", cardSign);

String configValue=jsonObject.toJSONString();

logger.info("configValue:"+configValue);returnconfigValue;

}/*** @desc :5.1获取发票签名

*

*@paramapiTicket 授权页ticket,见InvoiceService

*@paramappId

*@paramtimeStamp 时间戳

*@paramnonceStr 随机串

*@paramcardType 填入INVOICE

*@return*@throwsException

* String*/

public static String getCardSign(String apiTicket, String appId, String timeStamp, String nonceStr,String cardType) throwsException {//1.将 api_ticket、appid、timestamp、nonceStr、cardType的value值进行字符串的字典序排序。//注意:是value值值

String[] array = newString[] { apiTicket, appId, timeStamp, nonceStr,cardType};

StringBuffer sb= newStringBuffer();//字符串排序

Arrays.sort(array);for (int i = 0; i < 5; i++) {

sb.append(array[i]);

}

String plainTex=sb.toString();//String plainTex = apiTicket+appId+cardType+nonceStr+timeStamp;

System.out.println("plainTex:"+plainTex);try{

MessageDigest crypt= MessageDigest.getInstance("SHA-1");

crypt.reset();

crypt.update(plainTex.getBytes("UTF-8"));returnbyteToHex(crypt.digest());

}catch(NoSuchAlgorithmException e) {throw newException(e.getMessage());

}catch(UnsupportedEncodingException e) {throw newException(e.getMessage());

}

}public static String getSHA1(String apiTicket, String appId, String timeStamp, String nonceStr,String cardType) throwsException{

System.out.println("getSHA1-----------");try{

String[] array= newString[] { apiTicket, appId, timeStamp, nonceStr,cardType};

StringBuffer sb= newStringBuffer();//字符串排序

Arrays.sort(array);for (int i = 0; i < 5; i++) {

sb.append(array[i]);

}

String str=sb.toString();

logger.info("str:"+str);//SHA1签名生成

MessageDigest md = MessageDigest.getInstance("SHA-1");

md.update(str.getBytes());byte[] digest =md.digest();

StringBuffer hexstr= newStringBuffer();

String shaHex= "";for (int i = 0; i < digest.length; i++) {

shaHex= Integer.toHexString(digest[i] & 0xFF);if (shaHex.length() < 2) {

hexstr.append(0);

}

hexstr.append(shaHex);

}returnhexstr.toString();

}catch(Exception e) {

e.printStackTrace();throw new Exception("获取发票签名失败");

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值