场景:支付宝APP中扫码进入H5页面,用户授权登陆,获取用户支付宝用户的UID,头像,昵称。
支付宝官方文档链接:
https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.xZbtJT&treeId=284&articleId=106001&docType=1
先上效果
第一步:创建应用
想要调用该接口,需要先在开放平台管理中心的应用详情中开通获取用户信息的功能
第二步:配置密钥
开发者调用接口前需要先生成RSA密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后在开放平台管理中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)。
第三步:搭建和配置开发环境
- 下载服务端SDK
- 接口调用配置
AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY,
FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
第四步:调用接口获取用户信息
申请获取用户信息功能时默认可获取的用户信息包含用户ID、昵称、性别、省份、城市、用户头像、用户类型、用户状态、是否实名认证、是否是学生等信息。
授权流程
如上图所示,对于开发者而言,需要完成以下工作:
按照规则拼接授权页面的链接,并且引导用户跳转至该链接;
用户在授权页面上确认授权后,将跳转到开发者指定的回调页,并且带上auth_code;
开发者通过auth_code换取access_token及用户的userId;
如果需要除userId以外的其他信息,则使用access_token调用用户信息共享接口获取。
第一步:URL拼接与scope详解
url拼接规则:https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=APPID&scope=SCOPE&redirect_uri=ENCODED_URL
关于redirect_uri的说明:
接口会校验授权链接中配置的redirect_uri与应用中配置的授权链接是否一致。详细说明: 如果开发者在应用中配置的授权链接是:https://auth.example.com/authCallBack,则redirect_uri内容为https://auth.example.com/authCallBack的encode形式https%3A%2F%2Fauth.example.com%2FauthCallBack。授权回调地址对应的域名(auth.example.com)下的页面http://auth.example.com/authCallBack、https://auth.example.com/authRedirect、https://auth.example.com/都可以进行OAuth2.0授权。但与(auth.example.com)关联的二三级域名,如:http://www.example.com/、http://example.com/无法进行OAuth2.0授权。
关于scope的说明:
auth_base:以auth_base为scope发起的网页授权,是用来获取进入页面的用户的userId的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(通常是业务页面)。
auth_user:以auth_user为scope发起的网页授权,是用来获取用户的基本信息的(比如头像、昵称等)。但这种授权需要用户手动同意,用户同意后,就可在授权后获取到该用户的基本信息。若想获取用户信息,scope的值中需要有该值存在,如scope=auth_user,auth_base。
H5授权页面示例:
第二步:获取auth_code
当用户授权成功后,会跳转至开发者定义的回调页面,支付宝会在回调页面请求中加入参数,包括auth_code、app_id、scope等,需要注意的是支付宝仅保证auth_code、app_id以及scope参数的有效性。支付宝请求开发者回调页面示例如下:
http://example.com/doc/toAuthPage.html?app_id=app_id&source=alipay_wallet&scope=auth_user
&auth_code=ca34ea491e7146cc87d25fca24c4cD11
第三步:使用auth_code换取接口access_token及用户userId
接口名称:alipay.system.oauth.token
换取授权访问令牌,开发者可通过获取到的auth_code换取access_token和用户userId。auth_code作为换取access_token的票据,每次用户授权完成,回调地址中的auth_code将不一样,auth_code只能使用一次,一天未被使用自动过期。
接口请求示例
REQUEST URL: https://openapi.alipay.com/gateway.do
REQUEST METHOD: POST
CONTENT:
app_id=“app_id”
method=alipay.system.oauth.token
charset=GBK
sign_type=RSA2
timestamp=2014-01-01 08:08:08
sign=“sign”
version=1.0
grant_type=authorization_code
code=4b203fe6c11548bcabd8da5bb087a83b
refresh_token=201208134b203fe6c11548bcabd8da5bb087a83b
接口调用示例
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545}span.s1 {color: #e4af09}span.s2 {font: 12.0px 'PingFang SC'}
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());
} **catch** (AlipayApiException e) {
//处理异常
e.printStackTrace();
}
同步响应结果示例
{
"alipay_system_oauth_token_response": {
"access_token": "publicpBa869cad0990e4e17a57ecf7c5469a4b2",
"user_id": "user_id",
"alipay_user_id": "20881007434917916336963360919773",
"expires_in": 300,
"re_expires_in": 300,
"refresh_token": "publicpB0ff17e364f0743c79b0b0d7f55e20bfc"
},
"sign": "sign"
}
第四步:调用接口获取用户信息
如果scope=auth_base,在第三步就可以获取到用户的userId,无需走第四步。如果scope=auth_user,才需要走第四步,通过access_token调用用户信息共享接口获取用户信息。
接口名称:alipay.user.info.share
接口请求示例
REQUEST URL: https://openapi.alipay.com/gateway.do
REQUEST METHOD: POST
CONTENT:
app_id=app_id
method=alipay.user.info.share
charset=GBK
sign_type=RSA2
timestamp=2014-01-01 08:08:08
sign=sign
version=1.0
grant_type=authorization_code
code=4b203fe6c11548bcabd8da5bb087a83b
auth_token=201208134b203fe6c11548bcabd8da5bb087a83b
接口调用示例
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545}span.s1 {color: #e4af09}span.s2 {font: 12.0px 'PingFang SC'}
AlipayClient alipayClient = **new** DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
AlipayUserInfoShareRequest request = **new** AlipayUserInfoShareRequest();
String access_token = "composeBcd261a4867d94837a701f92816f18X18";
**try** {
AlipayUserInfoShareResponse userinfoShareResponse = alipayClient.execute(request, access_token);
System.out.println(userinfoShareResponse.getBody());
} **catch** (AlipayApiException e) {
//处理异常
e.printStackTrace();
}
同步响应结果示例
{
"alipay_user_info_share_response": {
"avatar": "https:\/\/tfsimg.alipay.com\/images\/partner\/T1k0xiXXRnXXXXXXXX",
"nick_name": "张三",
"city": "杭州",
"province": "浙江省",
"gender" : "M",
"user_type_value": "2",
"is_licence_auth": "F",
"is_certified": "T",
"is_certify_grade_a": "T",
"is_student_certified": "F",
"is_bank_auth": "T",
"is_mobile_auth": "T",
"alipay_user_id": "2088102015433735",
"user_id": "20881007434917916336963360919773",
"user_status": "T",
"is_id_auth": "T"
},
"sign": "jhoSkfE7BTIbwEx0L8/H0GU0Z2DOZYIJlrUMyJL8wwwInVeXfz+CWqx0V2b3FvhMQSrb74dkzDQpGXGdZQZMldGe4+FSEQU1V3tWijpO9ZisNJnEpF+U2lQ7IUMLsgjjx9a0IdMwvXlqz1HPrmFZQjG2dvlFyXhi07HcEnVOJZw="
}
java调用代码:
/**
* 支付宝支付授权获取Code
*
* @return
* @throws IOException
*/
@RequestMapping(value = "/V6/AliPayAuthorize", method = RequestMethod.GET)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
public void aliPayAuthorize(String auth_code) throws IOException { // String url
ResponseEntity responseEntity = new ResponseEntity();
// 通过code获取AccessToken
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
AlipayConfig.webapp_id, AlipayConfig.private_webapp_key,
"json","UTF-8", AlipayConfig.ali_public_webapp_key,"RSA2");
//获取用户信息授权
AlipaySystemOauthTokenRequest requestLogin2 = new AlipaySystemOauthTokenRequest();
requestLogin2.setCode(auth_code);
requestLogin2.setGrantType("authorization_code");
try {
AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(requestLogin2);
String accessToken = oauthTokenResponse.getAccessToken();
String userId = oauthTokenResponse.getUserId();
System.out.print("====================userId:"+userId);
System.out.print("====================accessToken:"+accessToken);
//调用接口获取用户信息
AlipayUserInfoShareRequest requestUser = new AlipayUserInfoShareRequest();
try {
AlipayUserInfoShareResponse userinfoShareResponse = alipayClient.execute(requestUser, oauthTokenResponse.getAccessToken());
if(userinfoShareResponse.isSuccess()){
System.out.print(userinfoShareResponse.getBody());
System.out.println("调用成功");
System.out.print("UserId:" + userinfoShareResponse.getUserId() + "\n");//用户支付宝ID
System.out.print("NickName:" + userinfoShareResponse.getNickName() + "\n");//用户支付宝昵称
System.out.print("UserType:" + userinfoShareResponse.getUserType() + "\n");//用户类型
System.out.print("UserStatus:" + userinfoShareResponse.getUserStatus() + "\n");//用户账户动态
System.out.print("Email:" + userinfoShareResponse.getEmail() + "\n");//用户Email地址
System.out.print("IsCertified:" + userinfoShareResponse.getIsCertified() + "\n");//用户是否进行身份认证
System.out.print("IsStudentCertified:" + userinfoShareResponse.getIsStudentCertified() + "\n");//用户是否进行学生认证
} else {
System.out.println("调用失败");
}
} catch (AlipayApiException e) {
//处理异常
e.printStackTrace();
}
} catch (AlipayApiException e) {
//处理异常
e.printStackTrace();
}
RequestContext.setResponseEntity(responseEntity);
}