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 getZhiFuBaoCode() throws Exception { // 授权地址 ,进行Encode转码 String authorizeURL = zhiFuBaoConstants.getAuthorizeURL(); // 回调地址 ,回调地址要进行Encode转码 String redirectUri = zhiFuBaoConstants.getRedirectURI(); //用于第三方应用防止CSRF攻击 String uuid = UUID.randomUUID().toString().replaceAll("-", ""); // 保存到Redis redisUtils.set(ZHIFUBAOSTATE + "-" + uuid, uuid, expiration, TimeUnit.MINUTES); // https://openauth.alipay.com/oauth2/publicAppAuthorize.htm? // app_id=appid // &scope=auth_user // &redirect_uri=redirectUri // &state=init // 拼接url StringBuilder url = new StringBuilder(); url.append(authorizeURL); url.append("?app_id=" + zhiFuBaoConstants.getAppID()); // 转码 url.append("&redirect_uri=" + URLEncodeUtil.getURLEncoderString(redirectUri)); url.append("&state=" + uuid); url.append("&scope=auth_user"); return ResponseEntity.ok(url); }
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 Map getToken(String code) throws Exception { Map zhiFuBaoProperties = 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(Map zhiFuBaoProperties) 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 "
}
5 个人网站(YOUYOUSHOP )(用户名:admin,密码:adminliyh),需要的小伙伴可以测试
5.1 每个人做的项目需求不同,可能会出现不同的问题,文章可以参考,也可以留言你的问题,我会帮你解决,大家一起加油