首页 » 技术分享 » 支付宝授权获取芝麻信用分数

支付宝授权获取芝麻信用分数

 

貌似好久没写文章了,今天来记录下最近用支付宝SDK获取芝麻信用分数的过程,以及踩过的坑。

个人感觉接芝麻信用分数时还是很简单的,基本都是服务端的任务,我们这边只需要将从支付宝授权获取的auth_code传给服务端,剩下的就是服务器的事了。但是还是有些小坑需要记录。

如果以后需要做支付宝登陆的,可以看这里,还是很详细的
Android 集成支付宝第三方登录

其实看官方的Demo也是很好的

踩坑一

当我把官方Demo下下来,配好APPID,PID,RSA2_PRIVATE之后,直接运行Demo直接蹦了,我就懵了,官方Demo居然会有问题,好吧,通过调试,定位是空指针

String oriSign = SignUtils.sign(authInfo.toString(), rsaKey, rsa2);

这里返回了null,无语了,通过网上查找问题,需要对其中封装好的方法修改

public static String sign(String content, String privateKey, boolean rsa2) {
    try {
        PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
                Base64.decode(privateKey));
    //后面需要下个"BC"参数          
        KeyFactory keyf = KeyFactory.getInstance(ALGORITHM, "BC");
        PrivateKey priKey = keyf.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.encode(signed);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

修改之后就不会返回null。

然后就可以通过将签名之后的参数传给AuthTask的authV2授权,授权成功之后就可以获取auth_code,然后传给服务器。

踩坑二

我从支付宝获取的auth_code传给服务器,服务器居然不能用,好吧,尴尬的我本来想去问支付宝技术人员的,但是后台人员说可以修改scope的value为auth_zhima,当我修改之后居然真的成功了,好吧,支付宝文档上居然没有记录,这文档真心烂。。。。

public static Map<String, String> buildAuthInfoMap(String pid, String app_id, String target_id, boolean rsa2) {
    Map<String, String> keyValues = new HashMap<String, String>();

    // 商户签约拿到的app_id,如:2013081700024223
    keyValues.put("app_id", app_id);

    // 商户签约拿到的pid,如:2088102123816631
    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", "auth_zhima");

    // 商户唯一标识,如:kkkkk091125
    keyValues.put("target_id", target_id);

    // 授权类型, 固定值
    keyValues.put("auth_type", "AUTHACCOUNT");

    // 签名类型
    keyValues.put("sign_type", rsa2 ? "RSA2" : "RSA");

    return keyValues;
}

注意:支付宝的芝麻信用分数获取和支付公用的一套SDK,并且授权用到的sign,需要从服务器获取,如果直接在客户端生成那是不安全的。

获取分数的部分代码

public class ZhiMaUtil {

    private static final int SDK_AUTH_Cacel = -1;
    private static final int SDK_AUTH_Fail = 0;
    private static final int SDK_AUTH_Success = 1;

    private Context mContext;
    private Callback mCallback;
    private String token;

    public ZhiMaUtil(Context context){
        this.mContext = context;
            }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_AUTH_Cacel: {
                    mCallback.getScoreFailed("用户取消授权");
                    break;
                }
                case SDK_AUTH_Fail: {
                    mCallback.getScoreFailed("授权失败");
                    break;
                }
                case SDK_AUTH_Success:{
                    AuthResult authResult = new AuthResult((Map<String, String>) msg.obj, true);
                    getMineService().getZmScore(token, authResult.getAuthCode()).enqueue(new retrofit2.Callback<BaseBean>() {
                        @Override
                        public void onResponse(Call<BaseBean> call, Response<BaseBean> response) {
                            if(response.isSuccessful()&&response.body() != null){
                                BaseBean baseBean = response.body();
                                mCallback.getScoreSuccess(baseBean.getData(), "获取分数成功");
                            }
                        }

                        @Override
                        public void onFailure(Call<BaseBean> call, Throwable t) {
                            mCallback.getScoreFailed("获取分数失败");
                            circleProgressDialog.dismiss();
                        }
                    });
                }
                default:
                    break;
            }
        }
    };

    public void zhiMaAuthTask(Callback callback){

        if(callback == null){
            throw new RuntimeException("callback can not null!!");
        }

        mCallback = callback;

        token = "Bearer "+Preferences.getInstance().getAccessToken(mContext);
        getMineService().getAuthSign(token).enqueue(new retrofit2.Callback<BaseBean>() {
            @Override
            public void onResponse(Call<BaseBean> call, final Response<BaseBean> response) {
                if(response.isSuccessful()&&response.body().getErrcode() == 0&&response.body()!=null){
                    BaseBean body = response.body();
                    Map<String, String> authInfoMap = OrderInfoUtil2_0.buildAuthInfoMap("你的pid", "你的app_id", String.valueOf(System.currentTimeMillis()), true);
                    String info = OrderInfoUtil2_0.buildOrderParam(authInfoMap);
                    final String authInfo = info + "&" + body.getData();
                    Runnable authRunnable = new Runnable() {

                        @Override
                        public void run() {
                            AuthTask authTask = new AuthTask((Activity) mContext);
                            // 调用授权接口,获取授权结果
                            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")){
                                Message msg = new Message();
                                msg.obj = result;
                                msg.what = SDK_AUTH_Success;
                                mHandler.sendMessage(msg);
                            }else if(TextUtils.equals(resultStatus, "6001")){
                                Message msg = new Message();
                                msg.what = SDK_AUTH_Cacel;
                                mHandler.sendMessage(msg);
                            }else {
                                Message msg = new Message();
                                msg.what = SDK_AUTH_Fail;
                                mHandler.sendMessage(msg);
                            }
                        }
                    };

                    // 必须异步调用
                    Thread authThread = new Thread(authRunnable);
                    authThread.start();
                }else if(response.body() != null){
                    LljApplication.showToastShort(response.body().getErrmsg());
                }
            }

            @Override
            public void onFailure(Call<BaseBean> call, Throwable t) {
                mCallback.getScoreFailed("获取分数失败");
            }
        });
    }

    public interface Callback{
        void getScoreSuccess(String score, String msg);
        void getScoreFailed(String msg);
    }

我们需要拷贝Demo里面的AuthResult,Base64,OrderInfoUtil2_0,SignUtils四个封装好的类。

上面代码是个工具类,功能还是很简单的,主要步骤如下:
1.获取服务器的sign,拼接客户端生成的info
2.通过拼接的参数,调用支付宝的SDK授权处理
3.获取auth_code,传给服务器获取分数
4.成功之后通过回调,传给ui显示

OK,芝麻信用分数获取成功。

转载自原文链接, 如需删除请联系管理员。

原文链接:支付宝授权获取芝麻信用分数,转载请注明来源!

1