网站支付宝登录授权具体实现

  • Post author:
  • Post category:其他


具体请参考官方文档: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 …