支付宝开放平台OAuth2授权与用户数据获取实战
沙箱环境配置
在正式接入前,需完成开发者账号注册与应用创建。进入支付宝开放平台控制台,创建应用后添加"第三方应用授权"与"会员信息获取"功能点。
由于未上线应用无法调用正式接口,需启用沙箱模式进行调试。关键配置项如下:
- 密钥类型:选择RSA2(推荐),无需再配置RSA1
- 密钥生成:使用支付宝密钥工具生成,获取私钥文件与公钥字符串
- 公钥上传:将公钥填入沙箱环境,同时保存支付宝公钥供验签使用
- 回调地址:本地调试可设置为 http://127.0.0.1:8080/callback
应用授权登录(App-to-AppAuth)
适用于商户应用获取其他商家授权场景,如代运营服务商模式。授权流程采用OAuth2授权码模式。
授权链接构建
<a href="https://openauth.alipaydev.com/oauth2/appToAppAuth.htm?app_id=2024XXXXXX&redirect_uri=http://127.0.0.1:8080/auth/callback">
支付宝授权登录
</a>
参数说明:app_id须使用沙箱应用ID,redirect_uri需与控制台配置保持一致。
授权回调处理
用户确认授权后,支付宝将携带app_auth_code跳转至回调地址。以下为Servlet处理示例:
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayOpenAuthTokenAppRequest;
import com.alipay.api.response.AlipayOpenAuthTokenAppResponse;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/auth/callback")
public class AuthCallbackServlet extends HttpServlet {
private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
private static final String APP_ID = "2024XXXXXXXXXXXX";
private static final String MERCHANT_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...";
private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
// 提取授权码
String authCode = req.getParameter("app_auth_code");
// 初始化客户端
AlipayClient client = new DefaultAlipayClient(
GATEWAY_URL, APP_ID, MERCHANT_PRIVATE_KEY,
"json", "UTF-8", ALIPAY_PUBLIC_KEY, "RSA2"
);
// 换取授权令牌
AlipayOpenAuthTokenAppRequest tokenReq = new AlipayOpenAuthTokenAppRequest();
tokenReq.setBizContent("{\"grant_type\":\"authorization_code\",\"code\":\"" + authCode + "\"}");
try {
AlipayOpenAuthTokenAppResponse tokenResp = client.execute(tokenReq);
if (tokenResp.isSuccess()) {
out.println("<h3>授权成功</h3>");
out.println("授权应用ID: " + tokenResp.getAuthAppId() + "<br>");
out.println("授权令牌: " + tokenResp.getAppAuthToken() + "<br>");
out.println("用户标识: " + tokenResp.getUserId());
// 持久化存储:app_auth_token有效期为12个月,需妥善保存
} else {
out.println("授权失败: " + tokenResp.getMsg());
}
} catch (AlipayApiException e) {
out.println("接口调用异常: " + e.getErrMsg());
}
}
}
合规提示:应用授权模式仅用于标识用户身份,禁止引导用户完善个人信息或进行用户导流。
用户信息授权(UserInfo)
如需获取用户昵称、头像、实名状态等详细信息,需申请auth_user scope权限。
scope权限说明
| 权限值 | 说明 | 交互方式 |
|---|---|---|
| auth_base | 仅获取用户ID(user_id) | 静默授权,无感知跳转 |
| auth_user | 获取完整用户信息 | 需用户手动确认授权 |
用户授权链接
<a href="https://openauth.alipaydev.com/oauth2/publicAppAuthorize.htm?
app_id=2024XXXXXX
&scope=auth_user
&redirect_uri=http://127.0.0.1:8080/user/callback">
获取用户信息
</a>
用户信息获取完整流程
回调处理需完成两步:先用auth_code换取access_token,再用令牌调用用户信息接口。
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
// 步骤一:换取访问令牌
AlipaySystemOauthTokenRequest oauthRequest = new AlipaySystemOauthTokenRequest();
oauthRequest.setCode(receivedAuthCode);
oauthRequest.setGrantType("authorization_code");
AlipaySystemOauthTokenResponse oauthResponse = client.execute(oauthRequest);
String accessToken = oauthResponse.getAccessToken();
// 步骤二:获取用户信息
AlipayUserInfoShareRequest userRequest = new AlipayUserInfoShareRequest();
AlipayUserInfoShareResponse userResponse = client.execute(userRequest, accessToken);
if (userResponse.isSuccess()) {
System.out.println("用户ID: " + userResponse.getUserId());
System.out.println("昵称: " + userResponse.getNickName());
System.out.println("头像: " + userResponse.getAvatar());
System.out.println("省份: " + userResponse.getProvince());
System.out.println("城市: " + userResponse.getCity());
System.out.println("用户类型: " + userResponse.getUserType());
System.out.println("实名认证: " + userResponse.getIsCertified());
System.out.println("学生认证: " + userResponse.getIsStudentCertified());
}
关键参数对照表
| 环境 | 授权网关 | 应用ID | 密钥配置 |
|---|---|---|---|
| 沙箱 | openapi.alipaydev.com | 沙箱APPID | 沙箱RSA2密钥 |
| 生产 | openapi.alipay.com | 正式APPID | 应用RSA2密钥 |
常见问题排查
- invalid app_id:检查是否混用沙箱与正式环境的APPID
- 验签失败:确认使用的是支付宝公钥而非应用公钥
- scope无效:检查应用是否已添加"获取会员信息"功能
- 中文乱码:确保请求与响应均使用UTF-8编码