本文只要是介绍如何通过restful后端服务实现支付宝的第三方登陆。
一、准备工作:
1、登陆支付宝开发平台,在网页/移动应用完成自己应用的创建
PS:注意这里绑定的商家账号,测试的时候填入个人的支付宝账号即可,应用类型选择网页应用。
2、开发配置:
PS:注意事项
- 接口价签方式选择使用 支付宝开放平台密钥工具 生成公钥和私钥,保存好公钥及私钥,因为我们不使用官方的SDK,后续接口请求加密的时候需 要使用到私钥。
- 授权回调地址配置网站根路径即可,不需要精确。
- 其他配置开启即可。
二、接口对接
1、时序图
2、授权页面URL拼接
https://openauth.alipay.com:443/oauth2/publicAppAuthorize.htm?app_id=2021004184670358&redirect_uri=https%3A%2F%2Faoneid-dev.ctcdn.cn%2F5d12425e42444de1a792aab466cbc3ab%2Fconnection%2Foidc%2Fd0ac8f5d2ddb5e3e9f992e04afd0e274%2Flogin%2Fcallback&scope=auth_user&response_type=code&state=4b92990e-0358-4893-9ad1-4f724af259d9
注意事项:
- baseRUL:https://openauth.alipay.com/oauth2/publicAppAuthorize.htmapp_id:申请应用的idscope:固定值 auth_user
- redirect_uri:为页面跳回地址(重定向地址),需要UrlDecode。
- state:随机串
- esponse_type:固定值 code
- scope: auth_user(根据需要权限加,分号隔开)
- app_id:申请应用时生成id
2、获取access_token
curl 'https://openapi.alipay.com/gateway.do?charset=UTF-8&method=alipay.system.oauth.token&format=json&sign=${sign}&app_id=${appid}&version=1.0&sign_type=RSA2×tamp=${now}' \
-F 'code=4b203fe6c11548bcabd8da5bb087a83b' \
-F 'grant_type=authorization_code'
注意事项
- baseUrl:https://openapi.alipay.com/gateway.do
- 请求方式:post
- method:alipay.system.oauth.token
- app_id:申请应用时生成id
- timestamp:yyyy-MM-dd HH:mm:ss格式当前时间
- sign:请求参数签名(生成规则下面有介绍)
- code:第一步返回时,url自带参数
- grant_type:固定值 authorization_code
3、获取用户信息
curl 'https://openapi.alipay.com/gateway.do?charset=UTF-8&method=alipay.user.info.share&format=json&sign=${sign}&app_id=${appid}&version=1.0&sign_type=RSA2×tamp=${now}' \
-F 'auth_token=${auth_token}'
注意事项:
- baseUrl:https://openapi.alipay.com/gateway.do
- 请求方式:post
- method:alipay.user.info.share
- app_id:申请应用时生成id
- timestamp:yyyy-MM-dd HH:mm:ss格式当前时间
- sign:请求参数签名(生成规则下面有介绍)
- auth_token:上一步返回的token
4、请求时自助签名生成
protected void signature(String privateKey,String content){
String privateKey = PropertiesConstants.transform(ctx,$privateKey,NULL);
String content = PropertiesConstants.transform(ctx, $content, NULL);;
try {
byte[] encodedKey = privateKey.getBytes();
encodedKey = org.bouncycastle.util.encoders.Base64.decode(encodedKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
Signature signature = Signature.getInstance("SHA256WithRSA");
signature.initSign(priKey);
signature.update(content.getBytes("utf-8"));
byte[] signed = signature.sign();
String decryptData = new String(Base64.encode(signed));
ctx.SetValue(id,decryptData.trim());
}catch (Exception e){
String errorMessage = "签名遭遇异常,请检查私钥格式是否正确。content=" + content + " privateKeySize=" + privateKey.length() + " reason=" + e.getMessage();
throw new BaseException("clnt.e5001", errorMessage);
}
}
注意事项:
content:将排序后的参数与其对应值,组合成 参数=参数值 的格式,并且把这些参数用 & 字符连接起来,此时生成的字符串为待签名字符串。
app_id=${oidc.app_id}&charset=UTF-8&code=${auth_code}&format=json&grant_type=authorization_code&method=${oidc.token_method}&sign_type=RSA2×tamp=${timestamp}&version=1.0
三、总结
阿里支付第三方登陆基本上遵行了oidc协议,不通的地方是请求的时候添加了官方签约认证,在不使用官方提供的SDK时,需要自行去下载他们源码,对源码进行改造后方可使用。