SpringBoot+Vue实现第三方支付宝登录(二)
1 支付宝登录授权流程
本步骤的作用:
登录 开放平台控制台 获取创建应用的 APPID
接入支付宝登录前,网站需首先进行申请,获得对应的appid,以保证后续流程中可正确对网站与用户进行验证与授权。
注意:对appid和appkey信息进行保密,不要随意泄漏。
2 放置“支付宝登录”按钮
本步骤的作用:
在网站页面上放置“支付宝登录”按钮,并为按钮添加前台代码,实现点击按钮即弹出支付宝登录对话框 。
2.1 下载“支付宝登录”按钮图片,并将按钮放置在页面合适的位置
按钮图片下载: 点击这里下载 。
可以到阿里矢量图库下载更多图标:阿里巴巴矢量图标库 。
按照UI规范,将按钮放置在页面合适的位置:点击这里查看 。
2.2 为“支付宝登录”按钮添加前台代码
2.2.1 效果演示
2.2.2 前端代码(Vue)
为了实现上述效果,应该为“支付宝登录”按钮图片添加如下前台代码:
第三方登录:
// 支付宝登录
handleZhiFuBaoLogin() {
this.dialogVisible = true;
this.pictureType = 'ZhiFuBaoLogin'
},
2.2.3 后端代码(Java)
支付宝登录配置文件信息:
# 支付宝登录配置
zhifubao.appID = 66666666 ( 替换成你的 )
zhifubao.redirectURI = https://www.youyoushop.work/zhiFuBaoCallback ( 替换成你的 )
zhifubao.authorizeURL = https://openauth.alipay.com/oauth2/publicAppAuthorize.htm
zhifubao.gateway = https://openapi.alipay.com/gateway.do
zhifubao.appPrivateKey = MIIujfisadjfeifjsaldjfjaejfufsdf0d8fsad ( 替换成你的私钥 )
zhifubao.alipayPublicKey = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlO1HqdX5uME+xdtMXY3JiKq27FbovsgdTUqaUKhF ( 替换成你的公钥 )
读取配置文件信息常量类:
package com.liyh.modules.security.constants;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Data
@Configuration
@PropertySource("classpath:thirdparty/config.properties") // 指定配置文件的路径,属性文件需放在根目录的resources文件夹下面,才能被读取出来
public class ZhiFuBaoConstants {
@Value("${zhifubao.appID}")
private String appID;
@Value("${zhifubao.redirectURI}")
private String redirectURI;
@Value("${zhifubao.authorizeURL}")
private String authorizeURL;
@Value("${zhifubao.gateway}")
private String gateway;
@Value("${zhifubao.appPrivateKey}")
private String appPrivateKey;
@Value("${zhifubao.alipayPublicKey}")
private String alipayPublicKey;
}
Conteoller(获取支付宝登录的url)
@ApiOperation("获得跳转到支付宝登录页的url")
@GetMapping("/getZhiFuBaoCode")
public ResponseEntity
3 使用Authorization_Code获取Access_Token
本步骤的作用:
通过用户验证登录和授权,获取Access Token,为下一步获取用户的OpenID做准备。
同时,Access Token是应用在调用OpenAPI访问和修改用户数据时必须传入的参数。
3.1 简介
即server-side模式,是OAuth2.0认证的一种模式,又称Web Server Flow。
适用于需要从web server访问的应用,例如Web网站。
对于应用而言,需要进行两步:
1. 获取Authorization Code。
2. 通过Authorization Code获取Access Token。
3.2 获取Authorization Code
示例代码
https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?
app_id=66666
&scope=auth_user
&redirect_uri=redirectUri
&state=init
请求参数:
参数 | 是否必须 | 含义 |
---|---|---|
app_id | 必须 | 开发者应用的app_id,相同支付宝账号下,不同的app_id获取的token切忌混用。 |
scope | 必须 | 接口权限值,目前只支持auth_user(获取用户信息、网站支付宝登录)、auth_base(用户信息授权)、auth_ecard(商户会员卡)、auth_invoice_info(支付宝闪电开票)、auth_puc_charge(生活缴费)五个值;多个scope时用”,”分隔,如scope为”auth_user,auth_ecard”时,此时获取到的access_token,可以用来获取用户信息 |
redirect_uri | 必须 | 授权回调地址,是经过URLENCODE转义 的url链接(url必须以http或者https开头); 在请求之前,开发者需要先到开发者中心对应应用内,配置授权回调地址。 redirect_uri与应用配置的授权回调地址域名部分必须一致。 |
state | 否 | 自定义参数,用户授权后,重定向到redirect_uri时会原样回传给商户。 为防止CSRF攻击,建议开发者请求授权时传入state参数,该参数要做到既不可预测,又可以证明客户端和当前第三方网站的登录认证状态存在 |
返回说明:
1. 如果用户成功登录并授权,则会跳转到指定的回调地址,并在redirect_uri地址后带上Authorization Code和原始的state值。如:
https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=APPID&scope=SCOPE&redirect_uri=ENCODED_URL
注意:此code会在10分钟内过期。
2. 如果用户在登录授权过程中取消登录流程,对于PC网站,登录页面直接关闭。
错误码说明:
接口调用有错误时,会返回code和msg字段,以url参数对的形式返回,value部分会进行url编码(UTF-8)。
PC网站接入时,错误码详细信息请参见:PC网站接入时的公共返回码
3.3 通过Authorization Code获取Access Token
请求说明:
支付宝登录和qq等第三方登录方式不一样,需要使用支付宝的依赖
com.alipay.sdk alipay-sdk-java 3.1.0
请求参数:
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
接口代码:
/**
* 获得token信息(授权,每个用户的都不一致) --> 获得token信息该步骤返回的token期限为一个月
*
* @return
* @throws Exception
*/
public MapgetToken(String code) throws Exception {
MapzhiFuBaoProperties = new HashMap ();
try {
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setGrantType("authorization_code");
request.setCode(code);
// AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
AlipayClient alipayClient = new DefaultAlipayClient(zhiFuBaoConstants.getGateway(), zhiFuBaoConstants.getAppID(), zhiFuBaoConstants.getAppPrivateKey(), "json", "GBK", zhiFuBaoConstants.getAlipayPublicKey(), "RSA2");
AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
// "user_id": "208834234652",
// "access_token": "2012234234231473993",
// "expires_in": "3600",
// "refresh_token": "2012234234473993",
// "re_expires_in": "3600"
String result = oauthTokenResponse.getAccessToken();
log.info("result = " + result);
// 把token保存
zhiFuBaoProperties = new HashMap();
zhiFuBaoProperties.put("accessToken", result);
} catch (Exception e) {
throw new BadRequestException("支付宝登录信息异常 !!!");
}
return zhiFuBaoProperties;
}
4 通过Access Token 获取用户信息
本步骤的作用:
通过输入在上一步获取的Access Token,得到对应用户的信息。
请求参数:
AlipayClient alipayClient = new DefaultAlipayClient
(zhiFuBaoConstants.getGateway(), zhiFuBaoConstants.getAppID(), zhiFuBaoConstants.getAppPrivateKey(), "json", "GBK", zhiFuBaoConstants.getAlipayPublicKey(), "RSA2");
接口代码:
/**
* accessToken 获取用户信息
*/
public AlipayUserInfoShareResponse getUserJson(MapzhiFuBaoProperties) throws Exception {
AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest ();
AlipayUserInfoShareResponse userInfo = new AlipayUserInfoShareResponse();
try {
// 取出token
String accessToken = (String) zhiFuBaoProperties.get("accessToken");
if (StringUtils.isEmpty(accessToken)) {
throw new BadRequestException("支付宝登录信息异常 !!!");
}
AlipayClient alipayClient = new DefaultAlipayClient(zhiFuBaoConstants.getGateway(), zhiFuBaoConstants.getAppID(), zhiFuBaoConstants.getAppPrivateKey(), "json", "GBK", zhiFuBaoConstants.getAlipayPublicKey(), "RSA2");
// 获取支付宝用户信息相关数据
userInfo = alipayClient.execute(request, accessToken);
// {
// "alipay_user_info_share_response": {
// "code": "10000",
// "msg": "Success",
// "user_id": "2088102104794936",
// "avatar": "http://tfsimg.alipay.com/images/partner/T1uIxXXbpXXXXXXXX",
// "province": "安徽省",
// "city": "安庆",
// "nick_name": "支付宝小二",
// "gender": "F"
// },
// "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE"
//}
} catch (Exception e) {
throw new BadRequestException("支付宝登录信息异常 !!!");
}
return userInfo;
}
返回数据:
{ "alipay_user_info_share_response": { "code": "10000", "msg": "Success", "user_id": "2088102104794936", "avatar": "http://tfsimg.alipay.com/images/partner/T1uIxXXbpXXXXXXXX", "province": "安徽省", "city": "安庆", "nick_name": "支付宝小二", "gender": "F" }, "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE" }