优化OauthApi授权 #64

This commit is contained in:
jinyu 2016-05-22 10:37:03 +08:00
parent 1aaee7c03d
commit 371b226a9b
3 changed files with 136 additions and 111 deletions

View File

@ -11,7 +11,6 @@ import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.mp.model.OauthToken; import com.foxinmy.weixin4j.mp.model.OauthToken;
import com.foxinmy.weixin4j.mp.model.User; import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.mp.type.Lang; import com.foxinmy.weixin4j.mp.type.Lang;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil; import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
/** /**
@ -28,44 +27,70 @@ public class OauthApi extends MpApi {
private final WeixinAccount account; private final WeixinAccount account;
/**
* 默认使用weixin4j.properties里面的appidappsecret信息
*/
public OauthApi() { public OauthApi() {
this(Weixin4jConfigUtil.getWeixinAccount()); this(Weixin4jConfigUtil.getWeixinAccount());
} }
/**
* 传入appidappsecret信息
*
* @param account
*/
public OauthApi(WeixinAccount account) { public OauthApi(WeixinAccount account) {
this.account = account; this.account = account;
} }
/** /**
* base静默授权:重定向URL使用weixin4j.properties#user.oauth.redirect.uri
*
* @see {@link #getAuthorizeURL(String, String,String)} * @see {@link #getAuthorizeURL(String, String,String)}
* *
* @return 请求授权的URL * @return 请求授权的URL
*/ */
public String getAuthorizeURL() { public String getAuthorizeURL() {
String appId = account.getId();
String redirectUri = Weixin4jConfigUtil String redirectUri = Weixin4jConfigUtil
.getValue("user.oauth.redirect.uri"); .getValue("user.oauth.redirect.uri");
return getAuthorizeURL(appId, redirectUri, "state", "snsapi_base"); return getAuthorizeURL(redirectUri, "state", "snsapi_base");
} }
/** /**
* 请求CODE * 请求CODE
* *
* @param appId
* 应用ID
* @param redirectUri * @param redirectUri
* 重定向地址 * 重定向地址<br>
* 1在微信公众号请求用户网页授权之前开发者需要先到公众平台官网中的开发者中心页配置授权回调域名请注意
* 这里填写的是域名是一个字符串而不是URL因此请勿加 http:// 等协议头<br>
* 2授权回调域名配置规范为全域名比如需要网页授权的域名为
* www.qq.com配置以后此域名下面的页面http://www.qq.com/music.html
* http://www.qq.com/login.html<br>
* 都可以进行OAuth2.0鉴权但http://pay.qq.com http://music.qq.com
* http://qq.com无法进行OAuth2.0鉴权<br>
* 3如果公众号登录授权给了第三方开发者来进行管理则不必做任何设置由第三方代替公众号实现网页授权即可
* @param state * @param state
* 用于保持请求和回调的状态授权请求后原样带回给第三方 * 用于保持请求和回调的状态授权请求后原样带回给第三方
* @param scope
* 应用授权作用域snsapi_base
* 不弹出授权页面直接跳转只能获取用户openidsnsapi_userinfo
* 弹出授权页面可通过openid拿到昵称性别所在地并且即使在未关注的情况下只要用户授权也能获取其信息<br>
* 1 以snsapi_base为scope发起的网页授权是用来获取进入页面的用户的openid的
* 并且是静默授权并自动跳转到回调页的用户感知的就是直接进入了回调页往往是业务页面<br>
* 2以snsapi_userinfo为scope发起的网页授权
* 是用来获取用户的基本信息的但这种授权需要用户手动同意并且由于用户同意过
* 所以无须关注就可在授权后获取该用户的基本信息<br>
* 3用户管理类接口中的获取用户基本信息接口是在用户和公众号产生消息交互或关注后事件推送后
* 才能根据用户OpenID来获取用户基本信息
* ,这个接口包括其他微信接口都是需要该用户即openid关注了公众号后才能调用成功的<br>
* @return 请求授权的URL * @return 请求授权的URL
*/ */
public String getAuthorizeURL(String appId, String redirectUri, public String getAuthorizeURL(String redirectUri, String state, String scope) {
String state, String... scopes) {
String sns_user_auth_uri = getRequestUri("sns_user_auth_uri"); String sns_user_auth_uri = getRequestUri("sns_user_auth_uri");
try { try {
return String.format(sns_user_auth_uri, appId, return String.format(sns_user_auth_uri, account.getId(),
URLEncoder.encode(redirectUri, Consts.UTF_8.name()), URLEncoder.encode(redirectUri, Consts.UTF_8.name()), scope,
StringUtil.join(scopes, ','), state); state);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
; ;
} }
@ -73,61 +98,38 @@ public class OauthApi extends MpApi {
} }
/** /**
* @see {@link #getOauthToken(String, String,String)} * code换取token
*
* @return
*/
public OauthToken getOauthToken(String code) throws WeixinException {
return getOauthToken(code, account.getId(), account.getSecret());
}
/**
* oauth授权code获取token
* *
* @param code * @param code
* 用户授权后返回的code * 用户同意授权获取的code
* @param appid * code作为换取access_token的票据每次用户授权带上的code将不一样code只能使用一次
* 应用ID * 5分钟未被使用自动过期
* @param appsecret * @return oauthtoken信息
* 应用密钥
* @return token对象
* @throws WeixinException
* @see com.foxinmy.weixin4j.mp.model.OauthToken
*/ */
public OauthToken getOauthToken(String code, String appid, String appsecret) public OauthToken getOauthToken(String code) throws WeixinException {
throws WeixinException {
String user_token_uri = getRequestUri("sns_user_token_uri"); String user_token_uri = getRequestUri("sns_user_token_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
user_token_uri, appid, appsecret, code)); user_token_uri, account.getId(), account.getSecret(), code));
return response.getAsObject(new TypeReference<OauthToken>() { return response.getAsObject(new TypeReference<OauthToken>() {
}); });
} }
/** /**
* @see {@link #getOauthToken(String, String,String)} * 刷新token由于access_token拥有较短的有效期当access_token超时后可以使用refresh_token进行刷新
* refresh_token有效期为30天当refresh_token失效之后需要用户重新授权
* *
* @return
*/
public OauthToken refreshToken(String refreshToken) throws WeixinException {
return refreshToken(account.getId(), refreshToken);
}
/**
* 刷新token
* *
* @param appId
* 应用ID
* @param refreshToken * @param refreshToken
* 填写通过access_token获取到的refresh_token参数 * 填写通过access_token获取到的refresh_token参数
* @return token对象 * {@link #getOauthToken(String)}
* @throws WeixinException * @see com.foxinmy.weixin4j.mp.model.OauthToken
* @return oauthtoken信息
*/ */
public OauthToken refreshToken(String appId, String refreshToken) public OauthToken refreshToken(String refreshToken) throws WeixinException {
throws WeixinException {
String sns_token_refresh_uri = getRequestUri("sns_token_refresh_uri"); String sns_token_refresh_uri = getRequestUri("sns_token_refresh_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
sns_token_refresh_uri, appId, refreshToken)); sns_token_refresh_uri, account.getId(), refreshToken));
return response.getAsObject(new TypeReference<OauthToken>() { return response.getAsObject(new TypeReference<OauthToken>() {
}); });
@ -185,6 +187,7 @@ public class OauthApi extends MpApi {
* @throws WeixinException * @throws WeixinException
* @see <a * @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN">授权获取用户信息</a> * href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN">授权获取用户信息</a>
* @see com.foxinmy.weixin4j.mp.model.OauthToken
* @see com.foxinmy.weixin4j.mp.model.User * @see com.foxinmy.weixin4j.mp.model.User
*/ */
public User getUser(String oauthToken, String openid, Lang lang) public User getUser(String oauthToken, String openid, Lang lang)

View File

@ -61,20 +61,25 @@ public class WeixinSuiteProxy {
this.suiteSettings = suiteSettings; this.suiteSettings = suiteSettings;
if (suiteSettings.getWeixinAccount().getSuiteAccounts() != null) { if (suiteSettings.getWeixinAccount().getSuiteAccounts() != null) {
this.suiteMap = new HashMap<String, SuiteApi>(); this.suiteMap = new HashMap<String, SuiteApi>();
for (WeixinAccount suite : suiteSettings.getWeixinAccount().getSuiteAccounts()) { for (WeixinAccount suite : suiteSettings.getWeixinAccount()
.getSuiteAccounts()) {
this.suiteMap.put(suite.getId(), new SuiteApi( this.suiteMap.put(suite.getId(), new SuiteApi(
new SuiteTicketHolder(suite.getId(), suite.getSecret(), suiteSettings.getTokenStorager0()))); new SuiteTicketHolder(suite.getId(), suite.getSecret(),
this.suiteMap.put(null, suiteSettings.getTokenStorager0())));
suiteMap.get(suiteSettings.getWeixinAccount().getSuiteAccounts().get(0).getId())); this.suiteMap.put(
null,
suiteMap.get(suiteSettings.getWeixinAccount()
.getSuiteAccounts().get(0).getId()));
} }
} }
if (StringUtil.isNotBlank(suiteSettings.getWeixinAccount().getId()) if (StringUtil.isNotBlank(suiteSettings.getWeixinAccount().getId())
&& StringUtil.isNotBlank(suiteSettings.getWeixinAccount().getProviderSecret())) { && StringUtil.isNotBlank(suiteSettings.getWeixinAccount()
this.providerApi = new ProviderApi( .getProviderSecret())) {
new TokenHolder( this.providerApi = new ProviderApi(new TokenHolder(
new WeixinProviderTokenCreator(suiteSettings.getWeixinAccount().getId(), new WeixinProviderTokenCreator(suiteSettings
suiteSettings.getWeixinAccount().getProviderSecret()), .getWeixinAccount().getId(), suiteSettings
suiteSettings.getTokenStorager0()), .getWeixinAccount().getProviderSecret()),
suiteSettings.getTokenStorager0()),
suiteSettings.getTokenStorager0()); suiteSettings.getTokenStorager0());
} }
} }
@ -122,7 +127,8 @@ public class WeixinSuiteProxy {
* 推送suite_ticket协议</a> * 推送suite_ticket协议</a>
* @throws WeixinException * @throws WeixinException
*/ */
public void cacheTicket(String suiteId, String suiteTicket) throws WeixinException { public void cacheTicket(String suiteId, String suiteTicket)
throws WeixinException {
suite(suiteId).getTicketHolder().cachingTicket(suiteTicket); suite(suiteId).getTicketHolder().cachingTicket(suiteTicket);
} }
@ -137,7 +143,8 @@ public class WeixinSuiteProxy {
* @throws WeixinException * @throws WeixinException
*/ */
public String getSuiteAuthorizeURL(String suiteId) throws WeixinException { public String getSuiteAuthorizeURL(String suiteId) throws WeixinException {
String redirectUri = Weixin4jConfigUtil.getValue("suite.oauth.redirect.uri"); String redirectUri = Weixin4jConfigUtil
.getValue("suite.oauth.redirect.uri");
return getSuiteAuthorizeURL(suiteId, redirectUri, "state"); return getSuiteAuthorizeURL(suiteId, redirectUri, "state");
} }
@ -157,9 +164,11 @@ public class WeixinSuiteProxy {
* @return 请求授权的URL * @return 请求授权的URL
* @throws WeixinException * @throws WeixinException
*/ */
public String getSuiteAuthorizeURL(String suiteId, String redirectUri, String state) throws WeixinException { public String getSuiteAuthorizeURL(String suiteId, String redirectUri,
String state) throws WeixinException {
try { try {
return String.format(URLConsts.SUITE_OAUTH_URL, suiteId, suite(suiteId).getTicketHolder().getTicket(), return String.format(URLConsts.SUITE_OAUTH_URL, suiteId,
suite(suiteId).getTicketHolder().getTicket(),
URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state); URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
; ;
@ -171,7 +180,8 @@ public class WeixinSuiteProxy {
* 第三方套件获取企业号管理员登录信息 * 第三方套件获取企业号管理员登录信息
* *
* @param authCode * @param authCode
* oauth2.0授权企业号管理员登录产生的code * oauth2.0授权企业号管理员登录产生的code:通过成员授权获取到的code每次成员授权带上的code将不一样
* code只能使用一次5分钟未被使用自动过期
* @return 登陆信息 * @return 登陆信息
* @see com.foxinmy.weixin4j.qy.api.ProviderApi * @see com.foxinmy.weixin4j.qy.api.ProviderApi
* @see <a href= * @see <a href=
@ -200,7 +210,8 @@ public class WeixinSuiteProxy {
* 获取登录企业号官网的url</a> * 获取登录企业号官网的url</a>
* @throws WeixinException * @throws WeixinException
*/ */
public String getLoginUrl(String corpId, LoginTargetType targetType, int agentId) throws WeixinException { public String getLoginUrl(String corpId, LoginTargetType targetType,
int agentId) throws WeixinException {
return providerApi.getLoginUrl(corpId, targetType, agentId); return providerApi.getLoginUrl(corpId, targetType, agentId);
} }
@ -215,7 +226,8 @@ public class WeixinSuiteProxy {
* @return * @return
*/ */
public WeixinProxy getWeixinProxy(String suiteId, String authCorpId) { public WeixinProxy getWeixinProxy(String suiteId, String authCorpId) {
return new WeixinProxy(suite(suiteId).getPerCodeHolder(authCorpId), suite(suiteId).getSuiteTokenHolder()); return new WeixinProxy(suite(suiteId).getPerCodeHolder(authCorpId),
suite(suiteId).getSuiteTokenHolder());
} }
public final static String VERSION = "1.6.9"; public final static String VERSION = "1.6.9";

View File

@ -27,45 +27,54 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
public class OauthApi extends QyApi { public class OauthApi extends QyApi {
private final WeixinAccount account; private final WeixinAccount account;
/**
* 默认使用weixin4j.properties里面的corpidcorpsecret信息
*/
public OauthApi() { public OauthApi() {
this(Weixin4jConfigUtil.getWeixinAccount()); this(Weixin4jConfigUtil.getWeixinAccount());
} }
/**
* 传入corpidappsecret信息
*
* @param account
*/
public OauthApi(WeixinAccount account) { public OauthApi(WeixinAccount account) {
this.account = account; this.account = account;
} }
/** /**
* 企业号用户身份授权 * 企业号用户身份授权:重定向URL使用weixin4j.properties#user.oauth.redirect.uri
* *
* @see {@link #getUserAuthorizeURL(String, String,String)} * @see {@link #getUserAuthorizeURL(String,String)}
* *
* @return 请求授权的URL * @return 请求授权的URL
*/ */
public String getUserAuthorizeURL() { public String getUserAuthorizeURL() {
String corpId = account.getId(); String redirectUri = Weixin4jConfigUtil
String redirectUri = Weixin4jConfigUtil.getValue("user.oauth.redirect.uri"); .getValue("user.oauth.redirect.uri");
return getUserAuthorizeURL(corpId, redirectUri, "state"); return getUserAuthorizeURL(redirectUri, "state");
} }
/** /**
* 企业号用户身份授权 * 企业号用户身份授权
* *
* @param corpId
* 企业号的corpid
* @param redirectUri * @param redirectUri
* 重定向地址 * 重定向地址
* @param state * @param state
* 用于保持请求和回调的状态 * 用于保持请求和回调的状态
* @return 请求授权的URL * @return 请求授权的URL
* @see UserApi
* @see {@link com.foxinmy.weixin4j.qy.WeixinProxy#getUserByCode(String)}
* @see <a href= * @see <a href=
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83"> * "http://qydev.weixin.qq.com/wiki/index.php?title=%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81">
* 企业号用户身份授权</a> * 企业号用户身份授权</a>
*/ */
public String getUserAuthorizeURL(String corpId, String redirectUri, String state) { public String getUserAuthorizeURL(String redirectUri, String state) {
String oauth_uri = getRequestUri("user_oauth_uri"); String oauth_uri = getRequestUri("user_oauth_uri");
try { try {
return String.format(oauth_uri, corpId, URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state); return String.format(oauth_uri, account.getId(),
URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
; ;
} }
@ -73,16 +82,16 @@ public class OauthApi extends QyApi {
} }
/** /**
* 企业号第三方提供商授权 * 企业号第三方提供商授权:重定向URL使用weixin4j.properties#third.oauth.redirect.uri
* *
* @see {@link #getThirdAuthorizeURL(String, String,String)} * @see {@link #getThirdAuthorizeURL(String,String)}
* *
* @return 请求授权的URL * @return 请求授权的URL
*/ */
public String getThirdAuthorizeURL() { public String getThirdAuthorizeURL() {
String corpId = account.getId(); String redirectUri = Weixin4jConfigUtil
String redirectUri = Weixin4jConfigUtil.getValue("third.oauth.redirect.uri"); .getValue("third.oauth.redirect.uri");
return getThirdAuthorizeURL(corpId, redirectUri, "state"); return getThirdAuthorizeURL(redirectUri, "state");
} }
/** /**
@ -98,13 +107,14 @@ public class OauthApi extends QyApi {
* @see ProviderApi * @see ProviderApi
* @see {@link com.foxinmy.weixin4j.qy.WeixinSuiteProxy#getOUserInfoByCode(String)} * @see {@link com.foxinmy.weixin4j.qy.WeixinSuiteProxy#getOUserInfoByCode(String)}
* @see <a href= * @see <a href=
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83"> * "http://qydev.weixin.qq.com/wiki/index.php?title=%E6%88%90%E5%91%98%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83">
* 企业号第三方提供商授权</a> * 企业号第三方提供商授权</a>
*/ */
public String getThirdAuthorizeURL(String corpId, String redirectUri, String state) { public String getThirdAuthorizeURL(String redirectUri, String state) {
String oauth_uri = getRequestUri("provider_oauth_uri"); String oauth_uri = getRequestUri("provider_oauth_uri");
try { try {
return String.format(oauth_uri, corpId, URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state); return String.format(oauth_uri, account.getId(),
URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
; ;
} }