提示:该博客主要记录自己学习工作中遇到的问题,以及一些解决方案,如果有不正确的地方,欢迎指出。大家共同学习,共同进步。
一、说明
支付宝授权问题主要分为两种情况:
- 网页和h5:https://opendocs.alipay.com/open/289/105656
- app登陆授权:https://opendocs.alipay.com/open/218/105326
二、对接流程
①网页、h5授权流程
②app授权流程
-
根据官方文档进行应用设置
-
引入依赖
<dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>3.1.0</version> </dependency>
-
拼接授权地址,返回给前端/原生
① 网页、h5拼接规则:
https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=APPID&scope=SCOPE&redirect_uri=ENCODED_URL
②app拼接规则
public static void main(String[] args) {
JSONObject params = new JSONObject();
String targetId = UUIDTools.getUUID32();
params.put("apiname", "alipay-sdk-java-3.1.0"); // sdk版本号
params.put("method", "alipay.open.auth.sdk.code.get"); // 固定值
params.put("app_id", "20171111111111"); // 应用appid
params.put("app_name", "mc"); // 固定值
params.put("biz_type", "openservice"); // 固定值
params.put("pid", "2088111111111111"); // 签约的支付宝账号对应的支付宝唯一用户号,以2088开头的16位纯数字组成
params.put("product_id", "APP_FAST_LOGIN");
params.put("scope", "kuaijie"); // 固定值
params.put("target_id", targetId); // 随机值
params.put("auth_type", "AUTHACCOUNT"); // 固定值
params.put("sign_type", "RSA2"); // 加密方式
// 1.对所有字段进行排序并加密
String content = sortParams(params,privateKeySecret);
String sign = contentsign(content,privateKeySecret); // privateKeySecret 支付宝设置的私钥
String encoderSign;
// 2.对加密后字段进行URLEncoder编码
try {
encoderSign = URLEncoder.encode(sign, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
System.out.println("URLencoder异常");
return;
}
// 3.拼接最终的url
StringBuffer sb = new StringBuffer();
sb.append("apiname=alipay-sdk-java-3.1.0&" +
"method=alipay.open.auth.sdk.code.get&" +
"app_id=20171111111111&" +
"app_name=mc&" +
"biz_type=openservice&" +
"pid=2088111111111111&" +
"product_id=APP_FAST_LOGIN&" +
"scope=kuaijie&" +
"tagrger_id=");
sb.append(targetId);
sb.append("&auth_type=AUTHACCOUNT&sign_type=RSA2&sign=");
sb.append(encoderSign);
System.out.println(sb.toString());
}
// 排序方法
public static String sortParams(Map<String, ?> data, String appKey) {
Set<String> keySet = data.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
Object value;
for (String k : keyArray) {
if (k == null || k.equals("") || k.equals(SignType.SIGN))
continue;
value = data.get(k);
if (value == null) {
data.remove(k);
continue;
}
sb.append(k).append("=").append(value).append("&");
}
if (StringUtils.isNotBlank(appKey))
sb.append("key=").append(appKey);
else
sb.delete(sb.length() - 1, sb.length());
return sb.toString();
}
// 签名方法
public static String sign(String content, String key) throws Exception {
String macIcon = "HmacSHA256";
Mac mac = Mac.getInstance(macIcon);
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), macIcon);
mac.init(secret_key);
byte[] array = mac.doFinal(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
- 第三步用户授权成功后,在回调地址中获取auth_code,后台根据autd_code获取accessToken
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setCode("2e4248c2f50b4653bf18ecee3466UC18");
request.setGrantType("authorization_code");
try {
AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
System.out.println(oauthTokenResponse.getAccessToken());
System.out.println(oauthTokenResponse.getUserId());
} catch (AlipayApiException e) {
//处理异常
e.printStackTrace();
}
- 获取到accessToken后就可以访问相关接口了