具体请参考官方文档:https://docs.open.alipay.com/263/105809/
本文由于支付宝官方并没有提供网站第三方登录的demo,因此笔者结合自己的实践经验做如下总结。
具体步骤:
Step One:创建应用
访问https://open.alipay.com/platform/home.htm,创建自己的应用,
如下图
因为我要实现的是网站使用支付宝登录,因此上图中选择”自定义接入”即可。接着 按照官方文档的步骤创建应用,提交审核即可。
Step Two:创建RSA密钥
为应用生成RSA密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY),生成密钥后在开放平台开发者中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)。
生成密钥的方式参考:https://docs.open.alipay.com/291/105971
注意:实际开发使用到的是支付宝公钥和应用私钥,
具体见下文。
设置完应用的RSA密钥后,可以查看支付宝公钥,如上图。
Step Three:编写程序实现支付宝第三方登录
官方提供的接口调用流程图下图所示:
首先,在Maven项目中引入依赖
第二步,在你的网站登录界面中,提供一个超链接,用于访问支付宝登录/授权页面,url格式:
https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=商户的APPID&scope=auth_user&redirect_uri=ENCODED_URL
请求参数主要有三个,分别是app_id、scope和redirect_uri。app_id就是你创建的应用的id;scope可以取的值有多个,这里使用”auth_user”实现网站授权登录,其他取值参见官方文档;最后的redirect_uri是授权成功后重定向的目标地址,一般映射到你后台的某个控制器,注意这里的url是需要经过编码的,这里提供一个在线编码的链接:http://tool.chinaz.com/Tools/urlencode.aspx。此外这里的URL需要同应用的“授权回调地址”保持一致!
本例子中redirect_uri是:
‘https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=xxxxxxxx&scope=auth_user&redirect_uri=http%3a%2f%2f106.14.149.152%3a8080%2falipay%2fgetAuthInfo.json
第三步:完成上述工作后,点击上面的超链接就会跳转到支付宝的授权登录页面:
完成授权后,浏览器会重定向到上述的redirect_uri地址,并且请求中会带有auth_code、app_id和scope等参数,因此需要在后台控制器中获取request中的auth_code参数
第四步:根据auth_code获取access_token,再根据access_token获取支付宝用户信息,具体代码如下:
(服务类)
/**
* 支付宝第三方登录
*
* @author minghui.y
* @create 2018-05-22 13:10
**/
@Service
public class AlipayLoginService implements InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(AlipayLoginService.class);
/**Alipay客户端*/
private AlipayClient alipayClient;
/**支付宝网关*/
private static final String ALIPAY_BORDER_DEV = “https://openapi.alipaydev.com/gateway.do”;
private static final String ALIPAY_BORDER_PROD = “https://openapi.alipay.com/gateway.do”;
/**appID**/
private static final String APP_ID_DEV = “xxxxxx”;
private static final String APP_ID_PROD = “xxxxxx”;
/**私钥*/
private static final String APP_PRIVATE_KEY = “xxxxxx”;
/**公钥*/
private static final String ALIPAY_PUBLIC_KEY = “xxxxx”;
@Override
public void afterPropertiesSet() throws Exception {
alipayClient = new DefaultAlipayClient(ALIPAY_BORDER_PROD, APP_ID_PROD, APP_PRIVATE_KEY, “json”, “UTF-8”, ALIPAY_PUBLIC_KEY, “RSA2”);
}
/**
* 根据auth_code获取用户的user_id和access_token
* @param authCode
* @return
*/
public String getAccessToken(String authCode) {
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setCode(authCode);
request.setGrantType(“authorization_code”);
try {
AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
return oauthTokenResponse.getAccessToken();
} catch (Exception e) {
LOGGER.error(“使用authCode获取信息失败!”, e);
return null;
}
}
/**
* 根据access_token获取用户信息
* @param token
* @return
*/
public AlipayUser getUserInfoByToken(String token) {
AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest ();
try {
AlipayUserInfoShareResponse response = alipayClient.execute(request, token);
if (response.isSuccess()) {
//打印响应信息
// System.out.println(ReflectionToStringBuilder.toString(response));
//封装支付宝对象信息
AlipayUser alipayUser = new AlipayUser();
alipayUser.setAddress(response.getAddress());
alipayUser.setCertNo(response.getCertNo());
alipayUser.setCity(response.getCity());
alipayUser.setCollegeName(response.getCollegeName());
alipayUser.setDegree(response.getDegree());
alipayUser.setMobile(response.getMobile());
alipayUser.setPhone(response.getPhone());
alipayUser.setProvince(response.getProvince());
alipayUser.setUserName(response.getUserName());
alipayUser.setNickName(response.getNickName());
return alipayUser;
}
LOGGER.error(“根据 access_token获取用户信息失败!”);
return null;
} catch (Exception e) {
LOGGER.error(“根据 access_token获取用户信息抛出异常!”, e);
return null;
}
}
}
(控制器)
/**
* 支付宝第三方登录服务
*
* @author minghui.y
* @create 2018-05-22 14:05
**/
@RestController
@RequestMapping(“/alipay”)
public class AlipayController {
@Autowired
private AlipayLoginService alipayLoginService;
@RequestMapping(“/getAuthInfo.json”)
public String getAuthCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println(“支付宝返回信息…………………………………………….”);
//从request中获取授权信息
String authCode = request.getParameter(“auth_code”);
String appID = request.getParameter(“app_id”);
String scope = request.getParameter(“scope”);
if (StringUtils.isNotEmpty(authCode)) {
//获取access_token
String accessToken = alipayLoginService.getAccessToken(authCode);
//获取用户信息
if (StringUtils.isNotEmpty(accessToken)) {
//获取用户信息
AlipayUser alipayUser = alipayLoginService.getUserInfoByToken(accessToken);
//存储到cookie中
Cookie cookieName = new Cookie(“account”, alipayUser.getNickName());
Cookie cookieRole = new Cookie(“roleName”, “支付宝账户”);
cookieName.setMaxAge(3600);
cookieRole.setMaxAge(3600);
cookieName.setPath(“/”);
cookieRole.setPath(“/”);
response.addCookie(cookieName);
response.addCookie(cookieRole);
//跳转至主界面
response.sendRedirect(“http://106.14.149.152:80/”);
}
}
return “hello alipay!”;
}
}
最后,在控制器中获取支付宝用户信息,重定向到登录成功后的主界面即可。这里需要注意的是,似乎只能获取支付宝用户的昵称、城市和省份这三个信息,其他的如地址、手机号登敏感信息是获取不到的,不过无伤大雅,因此这里实现的只是利用支付宝实现第三方登录而已。
.最最后,如何配置支付宝沙箱测试
支付宝的回调地址只能填写一个,如果项目已经上线了,那总不能一会把回调地址配置成生产的,一会配置成测试的吧,好在支付宝提供了一套供测试使用的沙箱环境,沙箱环境的文档地址如下:
https://docs.open.alipay.com/200/105311 ,也可以看我下面说的这些:
首先进入如下地址:https://openhome.alipay.com/platform/appDaily.htm?tab=info 配置沙箱环境,包括沙箱的网关,授权url,appid,公钥,密钥,均跟生产的都不同,需要重新配置,其中授权url如下:
https://openauth.alipaydev.com/oauth2/publicAppAuthorize.htm 。沙箱环境使用正常的支付宝账号也无法登录,必须要使用沙箱环境分配的账号,可以在下面地址中找到沙箱测试账号:https://openhome.alipay.com/platform/appDaily.htm?tab=account ,以上便是支付宝授权登录网站的开发流程。
Ending …