支付宝登录接入(Android/IOS(swift)/Java后台)

本文章仅作为个人笔记

截止发文在网上找了一圈支付宝登录的,大部分都是照搬官方的demo,没什么实际用处,官方的demo大家应该都看过了,对于Android来讲问题应该不大,后台就gg了,这里主写后台与Android对接心得。
因为实在被支付宝折腾的厉害,所以这里就不写什么注册处签约什么的流程了,心累,上些干货(代码),作为中国人自己的开放平台,文档还整理成这个样子需要自己琢磨代码的估计也就这一家了。也有可能是楼主自己语文或者检索能力不过关哦,如果看客发现有不规范或者不对的地方还望指出,这里先谢过了。
蚂蚁金服开放平台官网
支付宝Android官方接入文档
支付宝IOS官方接入文档
Android客户端demo&sdk下载地址(1.5.5)
IOS客户端demo&sdk下载地址(1.5.7)
服务器端接入官方文档
登录结果返回参数说明
支付结果返回参数说明
  • IOS端

    • 引入官方库(于Podfile文件加入如下内容并运行 pod install)

      pod 'AlipaySDK-iOS'
      
    • 于头文件添加如下内容,不知道什么是头文件的建议参考支付宝IOS官方接入文档

      #import <AlipaySDK/AlipaySDK.h>
      
    • 添加 URL Schemes ,设置为aliauth 并设置值为某一唯一值,如 包名.aliauth。设置为alipay 并设置值为某一唯一值,如 包名.alipay。

    • 与Localizable.strings 添加 “aliauthback” = “”//这里需要保持与上面的URL Schemes aliauth值一致。添加 “alipayback” = “”//这里需要保持与上面的URL Schemes alipay值一致。

    • 创建AliPayUtils工具文件

      		class AliPayUtils {
      		
      		    private static var aliAuthBack: AliPayBack?
      		    private static var aliPayBack: AliPayBack?
      		
      		    static func login(signStr: String, aliAuthBack: AliPayBack?) {
      		        AliPayUtils.aliAuthBack = aliAuthBack
      		        AlipaySDK().auth_V2(withInfo: signStr, fromScheme: NSLocalizedString("aliauthback", comment: ""), callback: { (resp) in
      		            loginBack(resultDic: resp as! [NSObject: AnyObject])
      		        })
      		    }
      		
      		    static func loginBack(resultDic: [NSObject: AnyObject]) {
      		        if let Alipayjson: [String: AnyObject] = resultDic as? [String: AnyObject] {
      		            let resultStatus = Alipayjson["resultStatus"] as! String
      		            print("loginBack resultStatus=\(resultStatus)")
      		            if resultStatus == "9000" {//	请求处理成功
      		                aliAuthBack?.finish(Alipayjson["result"] as? String)
      		            } else {
      		                aliAuthBack?.failed()
      		            }
      		        }
      		    }
      		
      		    static func pay(signStr: String, aliPayBack: AliPayBack?) {
      		        AliPayUtils.aliPayBack = aliPayBack
      		        AlipaySDK().payOrder(signStr, fromScheme: NSLocalizedString("alipayback", comment: ""), callback: { (resp) in
      		            payBack(resultDic: resp as! [NSObject: AnyObject])
      		        })
      		    }
      		
      		    static func payBack(resultDic: [NSObject: AnyObject]) {
      		        if let Alipayjson: [String: AnyObject] = resultDic as? [String: AnyObject] {
      		            let resultStatus = Alipayjson["resultStatus"] as! String
      		            print("payBack resultStatus=\(resultStatus)")
      		            if resultStatus == "9000" || resultStatus == "8000" {//   订单支付成功或正在处理中
      		                aliPayBack?.finish(Alipayjson["result"] as? String)
      		            } else {
      		                aliPayBack?.failed()
      		            }
      		        }
      		    }
      		
      		}
      		
      		protocol AliPayBack {
      		    func finish(_ result: String?)
      		
      		    func failed()
      		}
      
    • 于AppDelegate添加回调(这里贴主要代码)

      		@UIApplicationMain
      		class AppDelegate: UIResponder, UIApplicationDelegate {
      		
      		    func application(_ application: UIApplication, handleOpen url: URL) -> Bool {
      		        switch url.scheme {
      		        case NSLocalizedString("aliauthback", comment: ""):
      		            AlipaySDK().processAuth_V2Result(url) { (back) in
      		                AliPayUtils.loginBack(resultDic: back as! [NSObject: AnyObject])
      		            }
      		        case NSLocalizedString("alipayback", comment: ""):
      		            AlipaySDK().processOrder(withPaymentResult: url) { (back) in
      		                AliPayUtils.payBack(resultDic: back as! [NSObject: AnyObject])
      		            }
      		        default:
      		            print("handleOpenUrl1")
      		        }
      		        print("handleOpenUrl11=\(url.scheme)")
      		        return true
      		    }
      		
      		    func application(_ application: UIApplication, open url: URL
      		            , sourceApplication: String?, annotation: Any) -> Bool {
      		        switch url.scheme {
      		        case NSLocalizedString("aliauthback", comment: ""):
      		            AlipaySDK().processAuth_V2Result(url) { (back) in
      		                AliPayUtils.loginBack(resultDic: back as! [NSObject: AnyObject])
      		            }
      		        case NSLocalizedString("alipayback", comment: ""):
      		            AlipaySDK().processOrder(withPaymentResult: url) { (back) in
      		                AliPayUtils.payBack(resultDic: back as! [NSObject: AnyObject])
      		            }
      		        default:
      		            print("handleOpenUrl2")
      		        }
      		        print("handleOpenUrl12=\(url.scheme)")
      		        return true
      		    }
      		}
      
    • 登录调用(这里写部分伪代码):

      		//从服务器获取签名字符串,这里后面服务器开发会贴出,客户端可以不用管。
      		var signStr = getSignStrFromService()
      		AliPayUtils.login(signStr: result!, aliAuthBack: AliAuthBack())
      		//创建AliPayBack实例
      		struct AliAuthBack: AliPayBack {
      		
      		    func finish(_ result: String?) {
      		    	//登录成功,直接将获取的结果上传至服务器处理,服务器返回用户信息即可。
      		    }
      		
      		    func failed() {
      		    	//登录失败
      		    }
      		}
      
  • Android端

    • 接入前奏,注册签约的可另行百度,这里主要写代码部分

    • 下载jar包并导入(这里使用的是alipaySdk-20180601.jar)

    • 放入项目libs文件夹下

    • 与build.gradle导入jar(这里贴部分关键代码)

      	dependencies {
      	    implementation fileTree(dir: 'libs', include: ['*.jar'])
      	    implementation files('libs/alipaySdk-20180601.jar')
      	}
      
    • 于AndroidManifest.xml注册权限及activity(这里贴出部分关键代码)

      	<uses-permission android:name="android.permission.INTERNET" />
      	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
      	<uses-permission android:name="android.permission.READ_PHONE_STATE" />
      	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      	
      	<application>
      	    <activity
      	        android:name="com.alipay.sdk.app.H5PayActivity"
      	        android:configChanges="orientation|keyboardHidden|navigation|screenSize"
      	        android:exported="false"
      	        android:screenOrientation="behind"
      	        android:windowSoftInputMode="adjustResize|stateHidden" />
      	    <activity
      	        android:name="com.alipay.sdk.app.H5AuthActivity"
      	        android:configChanges="orientation|keyboardHidden|navigation"
      	        android:exported="false"
      	        android:screenOrientation="behind"
      	        android:windowSoftInputMode="adjustResize|stateHidden" />
      	</application>
      
      • 创建AliPayUtils工具文件(AuthResult/PayResult文件会后面贴出)

          		import android.app.Activity;
          		import android.text.TextUtils;
          		import android.util.Log;
          		
          		import com.alipay.sdk.app.AuthTask;
          		import com.alipay.sdk.app.EnvUtils;
          		import com.alipay.sdk.app.PayTask;
          		
          		import java.util.Map;
          		
          		public class AliPayUtils {
          		
          		    public interface Back {
          		        public void success(String result);
          		
          		        public void failed();
          		    }
          		
          		    public static void startPay(final Activity activity, final String orderInfo, final Back back) {
          		        if (orderInfo == null || back == null) {
          		            return;
          		        }
          		        new Thread(new Runnable() {
          		            @Override
          		            public void run() {
          		//                EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);//测试使用此设置
          		                EnvUtils.setEnv(EnvUtils.EnvEnum.ONLINE);//正式环境使用此设置
          		                PayTask alipay = new PayTask(activity);
          		                Map<String, String> result = alipay.payV2(orderInfo, true);
          		                PayResult payResult = new PayResult(result);
          		                String resultStatus = payResult.getResultStatus();
          		                if (TextUtils.equals(resultStatus, "9000")) {
          		                    back.success(payResult.getResult());
          		                } else {
          		                    back.failed();
          		                }
          		            }
          		        }).start();
          		    }
          		
          		    public static void login(final Activity activity, final String authInfo, final Back back) {
          		        if (authInfo == null || back == null) {
          		            return;
          		        }
          		        new Thread(new Runnable() {
          		            @Override
          		            public void run() {
          		                AuthTask authTask = new AuthTask(activity);
          		                Map<String, String> result = authTask.authV2(authInfo, true);
          		                AuthResult authResult = new AuthResult(result, true);
          		                String resultStatus = authResult.getResultStatus();
          		                if (TextUtils.equals(resultStatus, "9000")
          		                        && TextUtils.equals(authResult.getResultCode(), "200")) {
          		                    back.success(authResult.getResult());
          		                } else {
          		                    back.failed();
          		                }
          		            }
          		        }).start();
          		    }
          		
          		}
        
    • 创建AuthResult工具文件

      			import android.text.TextUtils;
      			
      			import java.util.Map;
      			
      			public class AuthResult {
      			
      				private String resultStatus;
      				private String result;
      				private String memo;
      				private String resultCode;
      				private String authCode;
      				private String alipayOpenId;
      			
      				public AuthResult(Map<String, String> rawResult, boolean removeBrackets) {
      					if (rawResult == null) {
      						return;
      					}
      			
      					for (String key : rawResult.keySet()) {
      						if (TextUtils.equals(key, "resultStatus")) {
      							resultStatus = rawResult.get(key);
      						} else if (TextUtils.equals(key, "result")) {
      							result = rawResult.get(key);
      						} else if (TextUtils.equals(key, "memo")) {
      							memo = rawResult.get(key);
      						}
      					}
      			
      					String[] resultValue = result.split("&");
      					for (String value : resultValue) {
      						if (value.startsWith("alipay_open_id")) {
      							alipayOpenId = removeBrackets(getValue("alipay_open_id=", value), removeBrackets);
      							continue;
      						}
      						if (value.startsWith("auth_code")) {
      							authCode = removeBrackets(getValue("auth_code=", value), removeBrackets);
      							continue;
      						}
      						if (value.startsWith("result_code")) {
      							resultCode = removeBrackets(getValue("result_code=", value), removeBrackets);
      							continue;
      						}
      					}
      			
      				}
      			
      				private String removeBrackets(String str, boolean remove) {
      					if (remove) {
      						if (!TextUtils.isEmpty(str)) {
      							if (str.startsWith("\"")) {
      								str = str.replaceFirst("\"", "");
      							}
      							if (str.endsWith("\"")) {
      								str = str.substring(0, str.length() - 1);
      							}
      						}
      					}
      					return str;
      				}
      			
      				@Override
      				public String toString() {
      					return "resultStatus={" + resultStatus + "};memo={" + memo + "};result={" + result + "}";
      				}
      			
      				private String getValue(String header, String data) {
      					return data.substring(header.length(), data.length());
      				}
      			
      				/**
      				 * @return the resultStatus
      				 */
      				public String getResultStatus() {
      					return resultStatus;
      				}
      			
      				/**
      				 * @return the memo
      				 */
      				public String getMemo() {
      					return memo;
      				}
      			
      				/**
      				 * @return the result
      				 */
      				public String getResult() {
      					return result;
      				}
      			
      				/**
      				 * @return the resultCode
      				 */
      				public String getResultCode() {
      					return resultCode;
      				}
      			
      				/**
      				 * @return the authCode
      				 */
      				public String getAuthCode() {
      					return authCode;
      				}
      			
      				/**
      				 * @return the alipayOpenId
      				 */
      				public String getAlipayOpenId() {
      					return alipayOpenId;
      				}
      			}  
      
    • 创建PayResult工具文件

      			import android.text.TextUtils;
      			
      			import java.util.Map;
      			
      			public class PayResult {
      				private String resultStatus;
      				private String result;
      				private String memo;
      			
      				public PayResult(Map<String, String> rawResult) {
      					if (rawResult == null) {
      						return;
      					}
      			
      					for (String key : rawResult.keySet()) {
      						if (TextUtils.equals(key, "resultStatus")) {
      							resultStatus = rawResult.get(key);
      						} else if (TextUtils.equals(key, "result")) {
      							result = rawResult.get(key);
      						} else if (TextUtils.equals(key, "memo")) {
      							memo = rawResult.get(key);
      						}
      					}
      				}
      			
      				@Override
      				public String toString() {
      					return "resultStatus={" + resultStatus + "};memo={" + memo
      							+ "};result={" + result + "}";
      				}
      			
      				/**
      				 * @return the resultStatus
      				 */
      				public String getResultStatus() {
      					return resultStatus;
      				}
      			
      				/**
      				 * @return the memo
      				 */
      				public String getMemo() {
      					return memo;
      				}
      			
      				/**
      				 * @return the result
      				 */
      				public String getResult() {
      					return result;
      				}
      			}
      
    • AliPayUtils登录使用方式:

      	//于服务器获取登录签名字符串(这里为伪代码),具体代码后面服务器先关会贴出。
      	String signStr = getSignStr();
      	//调用AliPayUtils登录方法
      	AliPayUtils.login(DemoActivity.this, signStr, new AliPayUtils.Back() {
      		    @Override
      		    public void success(String result) {
      		    	//登录成功,可将result上传至服务器处理。
      		    }
      	
      		    @Override
      		    public void failed() {
      		    	//登录失败
      		    }
      		});
      
  • 服务器端

    • Android客户端demo中写的“真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;”相信大家都看到了,也正是因为这句话楼主连appId都没有放客户端,但是官方并没有给出明确的解决方案。Android客户端jar包引入low到居然要下载jar文件放入,连gradle引入都不支持,无力吐槽。
    • 为了解决安全问题楼主不得不将加签所有过程放服务器端,那么问题来了:
      • 客户端的签名代码用的是客户端jar包,服务器端用的服务器jar包,且服务器根本没有签名示例代码。

      • 为此楼主只有强行将客户端部分代码照搬至服务器端,不管是否规范,至少签名在服务器这边处理是做到了。代码如下(代码真心多,但是为了一个类完成所有功能,只能勉强放一起了。):

          	import com.alipay.api.AlipayApiException;
          	import com.alipay.api.AlipayClient;
          	import com.alipay.api.DefaultAlipayClient;
          	import com.alipay.api.domain.AlipayTradeAppPayModel;
          	import com.alipay.api.domain.AlipayTradePrecreateModel;
          	import com.alipay.api.internal.util.AlipaySignature;
          	import com.alipay.api.request.*;
          	import com.alipay.api.response.*;
          	
          	import java.io.UnsupportedEncodingException;
          	import java.net.URLEncoder;
          	import java.security.KeyFactory;
          	import java.security.PrivateKey;
          	import java.security.Security;
          	import java.security.spec.PKCS8EncodedKeySpec;
          	import java.util.*;
          	
          	public class AliPayUtils {
          		private static final String APP_ID = "";//这个就不强调了,这个都找不到相比开发难度很大,我这文笔很难帮到你了。
          		private static final String PID = "";//在开放平台内点击右上角那里点击密钥管理,然后点击左边mapi网关产品密钥就能看到pid了。
          		private static final String APP_PRIVATE_KEY = "";//下面的这些信息在应用信息里边基本能看到,有些可能需要上传设置。
          	    private static final String RSA2_PRIVATE = "";//rsa2私钥
          	    private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzG+wSFicJ1BAP+/51vY8Zn4ZVNMgWuJCTAvfUh48QjixfJwYdr0lX8aOOHVLiC4zOBMdKi0Ale/R/myl1duCnWhCz9XgxMG/x5MpuxESU0SY6HZimW				wQGxoRmKsM3ICa7zmBa58nOig0cKY1ipJ6VXmTGSeiwF7TReKAGU8PeyYTZvnTgmIKofD7L8oAQF2xom3RlFbtzkjf4UaYbr+7m52dktPp6t7PwVKbbAiqDfVIoswrBaAPDmBWrf1Uaj8kt3KVzsiJzpN1xT0oRFikKj9KuMbIMI+ESpDr1674ToJa46AjI+0O8WxfQrebMuE/				xkUCG0WaQCXllLjtRXc7wIDAQAB";
          	    private static final String CHARSET = "UTF-8";
          	
          	    public static boolean alipayCallBack(Map<String, String[]> requestParams) {
          	        Boolean isPay = false;
          	        // 获取支付宝POST过来反馈信息
          	        Map<String, String> params = new HashMap<>();
          	        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
          	            String name = (String) iter.next();
          	            String[] values = requestParams.get(name);
          	            String valueStr = "";
          	            for (int i = 0; i < values.length; i++) {
          	                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
          	            }
          	            params.put(name, valueStr);
          	        }
          	        try {
          	            boolean flag = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, "RSA2");
          	            if (flag) {
          	                String tradeStatus = params.get("trade_status");
          	                if ("TRADE_SUCCESS".equals(tradeStatus)
          	                        || "TRADE_FINISHED".equals(tradeStatus)) {
          	                    String outTradeNo = params.get("out_trade_no");// 商户订单号
          	                    String tradeNo = params.get("trade_no");// 商户订单号
          	                    String gmtPayment = params.get("gmt_payment");// 支付时间
          	                    String gmtCreate = params.get("gmt_create");// 创建时间
          	
          	                }
          	            }
          	        } catch (AlipayApiException e) {
          	            e.printStackTrace();
          	        }
          	        return false;
          	    }
        
          	    public static AlipayTradeQueryResponse getPayInfo(String outTradeNo, String tradeNo) {
          	        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do"
          	                , APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
          	        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
          	        request.setBizContent("{" +
          	                "\"out_trade_no\":\"" + outTradeNo + "\"," +
          	                "\"trade_no\":\"" + tradeNo + "\"," +
          	                "\"org_pid\":\"" + PID + "\"" +
          	                "  }");
          	        try {
          	            return alipayClient.execute(request);
          	        } catch (AlipayApiException e) {
          	            return null;
          	        }
          	    }
          	
          	    public static String getPayStr(String totalAmount, String subject, String outTradeNo) {
          	        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do"
          	                , APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
          	        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
          	        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
          	        model.setSubject(subject);
          	        model.setOutTradeNo(outTradeNo);
          	        model.setTimeoutExpress("10m");
          	        model.setTotalAmount(totalAmount);
          	        model.setProductCode("QUICK_MSECURITY_PAY");
          	        request.setBizModel(model);
          	        request.setNotifyUrl("");//这里记得放支付回调地址
          	        try {
          	            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
          	            if (response.isSuccess()) {
          	                return response.getBody();
          	            } else {
          	                throw new BaseException(BaseResultEnum.ALIPAY_SIGN_ERROR);
          	            }
          	        } catch (AlipayApiException e) {
          	            throw new BaseException(BaseResultEnum.ALIPAY_SIGN_ERROR);
          	        }
          	    }
          	
          	    public static AlipayUserInfoShareResponse signAuthStr(String authCode) throws AlipayApiException {
          	        AlipayClient alipayClient = new DefaultAlipayClient(
          	                "https://openapi.alipay.com/gateway.do", APP_ID
          	                , APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY
          	                , "RSA2");
          	        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
          	        request.setGrantType("authorization_code");
          	        request.setCode(authCode);
          	        AlipayUserInfoShareRequest userInfoRequest = new AlipayUserInfoShareRequest();
          	        AlipaySystemOauthTokenResponse response =
          	                alipayClient.execute(request);
          	        if (response.isSuccess()) {
          	            AlipayUserInfoShareResponse userInfoResponse
          	                    = alipayClient.execute(userInfoRequest, response.getAccessToken());
          	            if (userInfoResponse.isSuccess()) {
          	                return userInfoResponse;
          	            }
          	            System.out.println("signAuthStr调用成功");
          	        } else {
          	            System.out.println("signAuthStr 调用失败");
          	        }
          	        return null;
          	    }
          	
          	    public static String getAuthStr() {
          	        Map<String, String> authInfoMap = buildAuthInfoMap();
          	        String info = buildOrderParam(authInfoMap);
          	        String sign = getSign(authInfoMap, RSA2_PRIVATE, true);
          	        return info + "&" + sign;
          	    }
          	
          	    private static String buildOrderParam(Map<String, String> map) {
          	        List<String> keys = new ArrayList<String>(map.keySet());
          	        StringBuilder sb = new StringBuilder();
          	        for (int i = 0; i < keys.size() - 1; i++) {
          	            String key = keys.get(i);
          	            String value = map.get(key);
          	            sb.append(buildKeyValue(key, value, true));
          	            sb.append("&");
          	        }
          	        String tailKey = keys.get(keys.size() - 1);
          	        String tailValue = map.get(tailKey);
          	        sb.append(buildKeyValue(tailKey, tailValue, true));
          	        return sb.toString();
          	    }
          	
          	    private static Map<String, String> buildAuthInfoMap() {
          	        Map<String, String> keyValues = new HashMap<String, String>();
          	        keyValues.put("app_id", APP_ID);
          	        keyValues.put("pid", PID);
          	        keyValues.put("apiname", "com.alipay.account.auth");
          	        keyValues.put("app_name", "mc");
          	        keyValues.put("biz_type", "openservice");
          	        keyValues.put("product_id", "APP_FAST_LOGIN");
          	        keyValues.put("scope", "kuaijie");
          	        keyValues.put("target_id", String.valueOf(System.currentTimeMillis())
          	                + new Random().nextInt(10000));
          	        keyValues.put("auth_type", "AUTHACCOUNT");
          	        keyValues.put("sign_type", "RSA2");
          	        return keyValues;
          	    }
          	
          	    private static String getSign(Map<String, String> map, String rsaKey
          	            , boolean rsa2) {
          	        List<String> keys = new ArrayList<String>(map.keySet());
          	        Collections.sort(keys);
          	        StringBuilder authInfo = new StringBuilder();
          	        for (int i = 0; i < keys.size() - 1; i++) {
          	            String key = keys.get(i);
          	            String value = map.get(key);
          	            authInfo.append(buildKeyValue(key, value, false));
          	            authInfo.append("&");
          	        }
          	        String tailKey = keys.get(keys.size() - 1);
          	        String tailValue = map.get(tailKey);
          	        authInfo.append(buildKeyValue(tailKey, tailValue, false));
          	        String oriSign = sign(authInfo.toString(), rsaKey, rsa2);
          	        String encodedSign = "";
          	        try {
          	            encodedSign = URLEncoder.encode(oriSign, "UTF-8");
          	        } catch (UnsupportedEncodingException e) {
          	            e.printStackTrace();
          	        }
          	        return "sign=" + encodedSign;
          	    }
          	
          	    private static String buildKeyValue(String key, String value, boolean isEncode) {
          	        StringBuilder sb = new StringBuilder();
          	        sb.append(key);
          	        sb.append("=");
          	        if (isEncode) {
          	            try {
          	                sb.append(URLEncoder.encode(value, "UTF-8"));
          	            } catch (UnsupportedEncodingException e) {
          	                sb.append(value);
          	            }
          	        } else {
          	            sb.append(value);
          	        }
          	        return sb.toString();
          	    }
          	
          	    private static final String ALGORITHM = "RSA";
          	
          	    private static final String SIGN_ALGORITHMS = "SHA1WithRSA";
          	
          	    private static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
          	
          	    private static final String DEFAULT_CHARSET = "UTF-8";
          	
          	    private static String getAlgorithms(boolean rsa2) {
          	        return rsa2 ? SIGN_SHA256RSA_ALGORITHMS : SIGN_ALGORITHMS;
          	    }
          	
          	    private static String sign(String content, String privateKey, boolean rsa2) {
          	        try {
          	            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
          	                    Base64.getDecoder().decode(privateKey));
          	            Security.addProvider(
          	                    new org.bouncycastle.jce.provider.BouncyCastleProvider());
          	            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, "BC");
          	            PrivateKey priKey = keyFactory.generatePrivate(priPKCS8);
          	            java.security.Signature signature = java.security.Signature
          	                    .getInstance(getAlgorithms(rsa2));
          	            signature.initSign(priKey);
          	            signature.update(content.getBytes(DEFAULT_CHARSET));
          	            byte[] signed = signature.sign();
          	            return Base64.getEncoder().encodeToString(signed);
          	        } catch (Exception e) {
          	            e.printStackTrace();
          	        }
          	        return null;
          	    }
          	
          	}
        
      • 贴完代码可能会有人代码报错,很正常,因为里边用到了官方没有说的代码(原始代码用的Android的jdk没问题,但是服务器端的部分jdk代码和客户端有差异,所以就报错了),解决方案:

         # gradle用户在build.gardle加入:
         "org.bouncycastle:bcprov-jdk16:1.45",
         # mvn用户在pom.xml加入:
         <dependency>
           <groupId>org.bouncycastle</groupId>
           <artifactId>bcprov-jdk16</artifactId>
           <version>1.45</version>
         </dependency>
        
      • 这样服务器端签名代码就写好(只是签名字符串),调用getAuthStr()方法就能返回了。

      • 首先将获得的realResult上传至服务器。然后我这边贴下服务器端的处理代码(首先是getAlipayAuthCode()方法,传入的是realResult,返回的是authCode,让后将获得的authCode传入signAuthStr()方法就获得了用户信息了,具体的信息可以参考官方文档):

          			private final String ALIPAY_AUTH_CODE_START = "auth_code=";
          			private final String ALIPAY_AUTH_CODE_END = "&";
          			private String getAlipayAuthCode(String response) {
          			    String result = response.substring(response.indexOf(ALIPAY_AUTH_CODE_START)
          			            + ALIPAY_AUTH_CODE_START.length(), response.length() - 1);
          			    return result.substring(0, result.indexOf(ALIPAY_AUTH_CODE_END));
          			}
          			public static AlipayUserInfoShareResponse signAuthStr(String authCode) throws AlipayApiException {
          			    AlipayClient alipayClient = new DefaultAlipayClient(
          			            "https://openapi.alipay.com/gateway.do", APP_ID
          			            , APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY
          			            , "RSA2");
          			    AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
          			    request.setGrantType("authorization_code");
          			    request.setCode(authCode);
          			    AlipayUserInfoShareRequest userInfoRequest = new AlipayUserInfoShareRequest();
          			    AlipaySystemOauthTokenResponse response =
          			            alipayClient.execute(request);
          			    if (response.isSuccess()) {
          			        AlipayUserInfoShareResponse userInfoResponse
          			                = alipayClient.execute(userInfoRequest, response.getAccessToken());
          			        if (userInfoResponse.isSuccess()) {
          			            return userInfoResponse;
          			        }
          			        System.out.println("signAuthStr调用成功");
          			    } else {
          			        System.out.println("signAuthStr 调用失败");
          			    }
          			    return null;
          			}
        
      • 获得了支付宝用户信息整个登录流程也基本结束了,剩下的就是自己业务逻辑的处理了,因为整个流程实在太复杂,写的可能有很多不详细的地方,还望谅解,发现不对的地方还望及时指正,有问题也可以评论指出。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页