2.小程序接口加签
首先下载 支付宝开放平台开发助手 生成私钥和公钥
顺便在配置一下接口内容加密方式
最后在能力管理中添加相关能力
# 支付宝配置 https://open.alipay.com/
ali:
# 支付宝分配给开发者的应用ID
appId: 2021003127613788
# 商户私钥,您的 PKCS8 格式 RSA2 私钥 (使用 支付宝开放平台开发助手 生成的应用私钥)
merchantPrivateKey: MIICi.......7zph
# 支付宝公钥 (支付宝加签后得到的公钥)
alipayPublicKey: MIIB......AQAB
# 签名方式
signType: RSA2
# 字符编码格式
charset: UTF-8
# 字符编码格式
format: json
# 支付宝网关
gatewayUrl: https://openapi.alipay.com/gateway.do
@Data
@Component
@ConfigurationProperties(prefix = "ali")
public class AliPayProperty {
/** 支付宝appID */
public String appId; /** 商户私钥,您的 PKCS8 格式 RSA2 私钥 (使用 支付宝开放平台开发助手 生成的应用私钥) */
public String merchantPrivateKey ;
/** 支付宝公钥,查看地址:https://openhome.alipay.com 对应 appID 下的支付宝公钥。 */
public String alipayPublicKey;
/** 接口格式规范 */
public String format;
/** 签名方式 */
public String signType;
/** 字符编码格式 */
public String charset;
/** 支付宝网关 https://openapi.alipay.com/gateway.do 这是正式地址 */
public String gatewayUrl;
/** 支付宝客户端 */
public AlipayClient getAlipayClient(){
AlipayClient alipayClient = new DefaultAlipayClient(
this.gatewayUrl,
this.appId,
this.merchantPrivateKey,
this.format,
this.charset,
this.alipayPublicKey,
this.signType);
return alipayClient;
}
}
@Data
public class AlipayAuthUser implements Serializable {
private static final long serialVersionUID = 647188207421940004L;
/** 支付宝用户的userId */
private String userId;
/** 系统用户ID */
private Long sysUserId;
/** 用户头像地址 */
private String avatar;
/** 性别(F:女 M:男) */
private String gender;
/** 昵称 */
private String nickName;
/** 省份 */
private String province;
/** 城市 */
private String city;
/** 创建时间 */
private Date createTime;
}
@RestController
public class AlipayController {
@Autowired
AliPayProperty aliPayProperty;
// 支付宝登录接口---支付宝小程序唤起登录后调用"
@GetMapping("/alipay/{authCode}")
public Object items(@PathVariable("authCode") String authCode) throws Exception {
System.out.println("授权码为: "+authCode);
AlipayAuthUser authUser = null;
// 1. 利用 授权码 authCode 获取 access_token、user_id
AlipaySystemOauthTokenResponse response = getAccessToken(authCode);
if (response.isSuccess()) {
/**
* 获取到用户信息后保存到数据库
* 1. 如果数据库不存在, 则注册
* 2. 如果存在,则获取数据库中的信息再返回
*/
String accessToken = response.getAccessToken();
String alipayUserId = response.getUserId();
System.out.println("accessToken: " + accessToken);
System.out.println("alipayUserId: " + alipayUserId);
// 2. ★★★这里是从数据库查询该用户是否存在的操作( 假设不存在---> null )
authUser = null;
if (authUser == null){
// 如果用户不存在,则通过支付宝api获取用户的信息后,再注册用户到自己平台数据库
AlipayUserInfoShareResponse aliUserInfo = getAliUserInfo(accessToken);
if (aliUserInfo != null) {
authUser = new AlipayAuthUser();
authUser.setUserId(alipayUserId);
authUser.setAvatar(aliUserInfo.getAvatar());
authUser.setNickName(aliUserInfo.getNickName());
authUser.setProvince(aliUserInfo.getProvince());
authUser.setCity(aliUserInfo.getCity());
authUser.setGender(aliUserInfo.getGender());
// ★★★这里应该进行数据库保存的逻辑( 这里直接打印输出查看 )
System.out.println("用户信息为: \n"+authUser);
}
}
}
if (authUser == null){
return "error";
}
return authUser;
}
/**
* 解密获取会员手机号
* 官方说明: https://opendocs.alipay.com/mini/api/getphonenumber
* 检验是否具有权限: https://open.alipay.com/api/check?examCode=E000001559
* */
@GetMapping("/getPhoneNumber")
public String getPhoneNumber(String response) throws Exception {
//1. 获取验签和解密所需要的参数
Map<String, String> openapiResult = jsON.parseObject(response,new TypeReference<Map<String, String>>() {}, Feature.OrderedField);
String signType = "RSA2"; //加签算法, 默认值
String encryptType = "AES"; //加签算法, 默认值
String charset = "UTF-8"; //验签和解密用的字符集, 默认值
String sign = openapiResult.get("sign");
String content = openapiResult.get("response");
//判断是否为加密内容
boolean isDataEncrypted = !content.startsWith("{");
boolean signCheckPass = false;
//2. 验签
String signContent = content;
String signVeriKey = aliPayProperty.getAlipayPublicKey(); //"你的小程序对应的支付宝公钥(为扩展考虑建议用appId+signType做密钥存储隔离)"
String decryptKey = "7nhiwn2N5fIpYZ2wsBm5hA==";//★★★你的小程序对应的接口加解密密钥(为扩展考虑建议用appId+encryptType做密钥存储隔离)
//如果是加密的报文则需要在密文的前后添加双引号
if (isDataEncrypted) {
signContent = "\"" + signContent + "\"";
} try {
signCheckPass = AlipaySignature.rsaCheck(signContent, sign, signVeriKey, charset, signType);
} catch (AlipayApiException e) {
// 验签异常, 日志
} if (!signCheckPass) {
//验签不通过(异常或者报文被篡改),终止流程(不需要做解密)
throw new Exception("验签失败");
}
//3. 解密
String plainData = null;
if (isDataEncrypted) {
try {
plainData = AlipayEncrypt.decryptContent(content, encryptType, decryptKey, charset);
} catch (AlipayApiException e) {
//解密异常, 记录日志
throw new Exception("解密异常");
}} else {
plainData = content;
}
System.out.println(plainData);
return plainData;
}
/** 用授权码获取 access_token, user_id
* 官方文档: https://opendocs.alipay.com/open/02ailc */
private AlipaySystemOauthTokenResponse getAccessToken(String autoCode) throws AlipayApiException {
AlipayClient alipayClient = aliPayProperty.getAlipayClient();
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setGrantType("authorization_code");//请求参数 grant_type
request.setCode(autoCode);//请求参数,授权码 code
// request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");//请求参数 refresh_token
AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
System.out.println("返回的信息: "+response.getBody());
if(response.isSuccess()){
System.out.println("获取access_token成功");
return response;
} else {
System.out.println("获取access_token失败");
return null;
}
}
/** 获取支付宝用户信息
* 官方文档: https://opendocs.alipay.com/open/02aild */
private AlipayUserInfoShareResponse getAliUserInfo (String accessToken) throws Exception {
AlipayClient alipayClient = aliPayProperty.getAlipayClient();
AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
AlipayUserInfoShareResponse response = alipayClient.execute(request,accessToken);
if(response.isSuccess()){
System.out.println("获取用户信息成功");
return response;
} else {
System.out.println("获取用户信息失败");
return null;
}
}
}
// 支付宝授权登录
my.getAuthCode({
scopes: ['auth_user'],
success: res => {
console.log(jsON.stringify(res));
if (res.authCode) {
my.request({
url: '后端支付宝登录接口', //将授权码 res.authCode 发给后端进行登录处理
method: 'GET',
data: {
authCode: res.authCode
},
success: res => {
console.log(res);
},
fail: res => {
console.log(res);
}
});
}
}
});
// 支付宝获取用户手机号
my.getPhoneNumber({
success: (res) => {
let encryptedData = res.response;
my.request({
url: '你的后端电话号解密接口',
data: encryptedData,
});
},
fail: (res) => {
console.log(res);
console.log('getPhoneNumber_fail');
},
});
0条评论