前言
一键登录的思路是
获取支付宝账号的手机号,如果手机号已存在就自动登录,如果不存在就生成该手机号的账号信息,当然也可以让用户绑定自己的账号信息。
所以我们要先获取手机号:
https://opendocs.alipay.com/mini/api/getphonenumber?pathHash=a67c2790
注意
获取会员手机号仅对企业支付宝账户开放,个人账号不支持,详见获取会员手机号。
获取会员手机号仅对企业支付宝账户开放,个人账号不支持,详见获取会员手机号。
获取会员手机号仅对企业支付宝账户开放,个人账号不支持,详见获取会员手机号。
常用地址
开放平台
https://open.alipay.com/develop/manage
创建小程序
https://open.alipay.com/develop/mini/create?bundleId=com.alipay.alipaywallet&from=createMenuPage
小程序API
https://opendocs.alipay.com/mini/api/
获取手机号
https://opendocs.alipay.com/mini/api/getphonenumber
获取用户信息
方式1
my.getAuthCode 引导用户授权其信息给当前小程序,取得的代表用户授权的授权码(authCode),
后续需由小程序服务端使用,向支付宝换取用户信息(如 user_id(open_id)、头像、昵称、手机号、地区、性别、出生日期等)。
这种方式较通用,但也相对复杂。
获取不到用户的ID,用户ID需要小程序获取authCode发给后台,后台获取。
https://opendocs.alipay.com/mini/api/openapi-authorize?pathHash=22642781
后台
https://opendocs.alipay.com/open/84bc7352_alipay.system.oauth.token?scene=common&pathHash=fe1502d5
方式2
对于简单需求
获取用户昵称和头像,请使用 my.getOpenUserInfo;
获取用户手机号,请使用 my.getPhoneNumber。
方式1 后台获取
小程序获取授权码,后台获取用户openid、昵称、头像、手机号。
https://opendocs.alipay.com/mini/api/openapi-authorize?pathHash=22642781
对应权限的申请位置
在线调试
https://open.alipay.com/api/apiDebug?apiNames=alipay.system.oauth.token&frontProdCode=I1080300001000042699&backProdCode=I1220100001000025884
步骤
- 小程序获取授权码
页面
1
| <button open-type="getAuthorize" scope="userInfo" @getAuthorize="getOpenUserInfo"> 会员基础信息授权 </button>
|
JS
1 2 3 4 5 6 7 8 9 10 11
| getOpenUserInfo: function () { my.getAuthCode({ scopes: 'auth_user', success: (authCodeRes) => { const authCode = authCodeRes.authCode; }, fail: (error) => { console.error('获取授权码失败', error); } }); },
|
- 服务端通过授权码获取用户信息
服务端使用 authCode,调用 alipay.system.oauth.token 取得 user_id(open_id) 和 token(授权令牌)。
服务端继续使用所取得的 token 调用 alipay.user.info.share 最终获得用户信息。
方式2
这种方式
小程序获取授权码,后台获取用户openid、昵称、头像
小程序获取手机号
小程序获取用户的基本信息及加密的手机号,后台解密手机号。
只能获取用户的昵称、头像、手机号,用手机号作为唯一标识。
获取用户基本信息
获取用户基本信息不用在小程序的后台申请权限/
1 2 3 4 5 6 7 8 9 10
| my.getOpenUserInfo({ success: (userInfoRes) => { const userInfo = JSON.parse(userInfoRes.response).response; console.log('User Info:', userInfo); }, fail: (error) => { console.error('获取用户信息失败', error); } });
|
获取用户信息不用解密,用户信息仅包含用户的昵称和头像。
用户信息中能获取到的是avatar和nickName
小程序获取手机号
申请权限

小程序
页面中
1 2 3 4
| <button class="login" type="default" open-type="getAuthorize" @getAuthorize="onGetAuthorize" @error="onAuthError" scope='phoneNumber'>授权手机号一键登录</button>
|
JS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| onGetAuthorize: function() { return new Promise((resolve, reject) => { my.getPhoneNumber({ scopes: "auth_user", success: res => { console.info("response", res.response); this.zfbLogin(res.response); resolve(res); }, fail: res => { reject(res); } }); }); },
|
response 是一个JSON对象转的字符串,包含两个属性:
response和sign,我们可以前端取传给后端,也可以传整个字符串让后端解析。
服务端解密
添加引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <dependencies> <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>4.39.74.ALL</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.50</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.3.2</version> </dependency> </dependencies>
|
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.parser.Feature; import com.alipay.api.AlipayApiException; import com.alipay.api.internal.util.AlipayEncrypt; import com.alipay.api.internal.util.AlipaySignature;
import java.util.Map;
public class MyTest { public static void main(String[] args) throws Exception { String response = "{\"response\":\"xxxxxxx\",\"sign\":\"xxx\"}";
getResult(response); }
public static String getResult(String response) throws Exception { Map<String, String> openapiResult = JSON.parseObject(response, new TypeReference<Map<String, String>>() { }, Feature.OrderedField);
String sign = openapiResult.get("sign"); String content = openapiResult.get("response"); boolean isDataEncrypted = !content.startsWith("{"); boolean signCheckPass = false; String signType = "RSA2"; String charset = "UTF-8"; String encryptType = "AES"; String signContent = content; String signVeriKey = "你的小程序对应的支付宝公钥(为扩展考虑建议用appId+signType做密钥存储隔离)"; String decryptKey = "你的小程序对应的加解密密钥(为扩展考虑建议用appId+encryptType做密钥存储隔离)"; if (isDataEncrypted) { signContent = "\"" + signContent + "\""; } try { signCheckPass = AlipaySignature.rsaCheck(signContent, sign, signVeriKey, charset, signType); } catch (AlipayApiException e) { } if (!signCheckPass) { throw new Exception("验签失败"); } 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:" + plainData); return plainData; } }
|
新的要求
https://open.alipay.com/portal/forum/post/173201040
只获取用户openid可以静默获取
静默获取用户的openid
1 2 3 4 5 6 7 8 9 10 11
| getOpenUserInfo: function () { my.getAuthCode({ scopes: 'auth_base', success: (authCodeRes) => { const authCode = authCodeRes.authCode; }, fail: (error) => { console.error('获取授权码失败', error); } }); },
|