美文网首页tool for workiOS要做的小项目
支付宝登录接入(Android/IOS(swift)/Java后

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

作者: 草丛里的黄盖 | 来源:发表于2018-10-02 12:33 被阅读46次

    本文章仅作为个人笔记

    截止发文在网上找了一圈支付宝登录的,大部分都是照搬官方的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;
                        }
          
        • 获得了支付宝用户信息整个登录流程也基本结束了,剩下的就是自己业务逻辑的处理了,因为整个流程实在太复杂,写的可能有很多不详细的地方,还望谅解,发现不对的地方还望及时指正,有问题也可以评论指出。

    相关文章

      网友评论

        本文标题:支付宝登录接入(Android/IOS(swift)/Java后

        本文链接:https://www.haomeiwen.com/subject/kdapoftx.html