Android 微信支付宝授权获取用户信息

**

Android 微信支付宝授权

**
最近项目中要实现微信支付宝授权获取用户信息以及支付,在网上查了很多资料,项目中将两个平台的收取与支付写在了一起,记录一下以便以后使用时查看。

1. 微信&支付宝sdk下载

一、微信平台&支付宝平台申请应用

微信开放平台(默认你已经注册了微信开发平台账号,微信支付需要开发者资质验证好像是300大洋,一般由公司提供账号)创建应用,如下图,在管理中心创建应用,按提示操作进行就行,没什么难的

在这里插入图片描述
应用通过以后在 开发信息 中填上你应用的应用包名和应用签名
填写的包名一定要跟你要集成的APP的包名一致,也就是你项目下,AndroidManifest文件下的pakage或者build.gradle文件下的applicationid
AndroidManifest:在这里插入图片描述
app->build.gradle:在这里插入图片描述
获取应用签名:
1、微信开放平台下载开发工具包(SDK)和签名工具

在这里插入图片描述在这里插入图片描述A==/dissolve/70)

2、将下载的“签名工具”APK,安装到手机。在该手机上安装你打包的应用的APK并运行,通过签名生成工具输入包名get signature获取应用签名,填写到微信开发平台,平台会分配给你AppID和AppSecret。

在这里插入图片描述
支付宝应用申请与微信类似,得到PID,APPID和RSA2_PRIVATE
支付宝开放平台下载sdk
官网地址下载sdk和demo
在这里插入图片描述

二、项目中使用

1、将wechat-sdk-android-with-mta-1.0.2.jar和alipaySdk-20160223.jar 拷贝到我们工程的libs下,并添加到依赖中

在这里插入图片描述
Android Studio环境下:已改用gradle形式,使用gradle来编译、更新微信SDK。

在build.gradle文件中,添加如下依赖即可:

dependencies {

compile ‘com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+’

}

dependencies {

compile ‘com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+’

}
2、配置AndroidManifest添加如下代码:

权限

<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" />
//微信
<activity
            android:name=".wxapi.WXEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@android:style/Theme.Translucent">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="微信给你的AppID" />
            </intent-filter>
        </activity>
         <activity
            android:name=".wxapi.WXPayEntryActivity"
            android:exported="true"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="wx8d024c5351b07056" />
            </intent-filter>
        </activity>
        //支付宝
        <!-- alipay sdk begin -->
        <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" />
        <!-- alipay sdk end -->

2、微信需要在项目中有回调类处理微信返回的信息,必须在你app包名下面新建文件夹wxapi,然后新建类名必须为:授权: WXEntryActivity,支付:WXPayEntryActivity
在这里插入图片描述
项目中使用微信&支付宝请求授权的代码:

 public class AuthUtils {

    /** 支付宝支付业务:入参app_id */
    public static final String APPID = "你的APPID";
    /** 支付宝账户登录授权业务:入参pid值 */
    public static final String PID = "你的PID";
    /** 支付宝账户登录授权业务:入参target_id值 */
    public static final String TARGET_ID = "1";
    public static final String RSA2_PRIVATE = "你的RSA2_PRIVATE ";
    public static final String RSA_PRIVATE = "";

    private static Context mContext;
    private static final int SDK_AUTH_FLAG=1002;

    public static String userId="";
    public static String authCode="";

    private static AliAuthBack mAliAuthBack;


    /**
     * 调用支付宝的授权
     * @param content 后台传过来的数据
     * @param context 上下文
     */
    public static void  setAliAuth(final String content,Context context){
        mContext=context;

        //检测是否安装支付宝
        Uri uri=Uri.parse("alipays://platformapi/startApp");
        Intent intent=new Intent(Intent.ACTION_VIEW,uri);
        ComponentName componentName=intent.resolveActivity(context.getPackageManager());
        //确认安装支付宝后进行授权接口调用
        if(componentName!=null){
            boolean rsa2 = (RSA2_PRIVATE.length() > 0);
            Map<String, String> authInfoMap = OrderInfoUtil2_0.buildAuthInfoMap(PID, APPID, TARGET_ID, rsa2);
            String info = OrderInfoUtil2_0.buildOrderParam(authInfoMap);

            String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;
            String sign = OrderInfoUtil2_0.getSign(authInfoMap, privateKey, rsa2);
            final String authInfo = info + "&" + sign;
            //异步处理
            Runnable authRunnable=new Runnable() {
                @Override
                public void run() {

                    //构造AuthTask对象
                    AuthTask authTask=new AuthTask((Activity)mContext);
                    //调用授权接口,获取授权结果
                    Map<String,String >result=authTask.authV2(authInfo,true);

                    Message msg=new Message();
                    msg.what=SDK_AUTH_FLAG;
                    msg.obj=result;
                    mHandler.sendMessage(msg);
                }
            };
            //必须异步处理
            Thread authThread=new Thread(authRunnable);
            authThread.start();
        }else{
            ToastUtil.show("请您先安装支付宝");
        }
    }



    private static Handler mHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case SDK_AUTH_FLAG:
                AuthResult authResult = new AuthResult((Map<String, String>) msg.obj, true);
                String resultStatus = authResult.getResultStatus();
                // 判断resultStatus 为“9000”且result_code
                // 为“200”则代表授权成功,具体状态码代表含义可参考授权接口文档
                if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {
                    // 获取alipay_open_id,调支付时作为参数extern_token 的value
                    // 传入,则支付账户为该授权账户
                    if(mAliAuthBack!=null){
                        mAliAuthBack.authInfo(authResult.getAuthCode(),authResult.getUserId());
                    }
//                    Toast.makeText(mContext, "授权成功\n" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT)
//                            .show();
                    Toast.makeText(mContext, "授权成功", Toast.LENGTH_SHORT)
                            .show();
                } else {
                    // 其他状态值则为授权失败
                    Toast.makeText(mContext, "授权失败", Toast.LENGTH_SHORT).show();

                }
                break;
            }
        }
    };



    private  void setAuthCode(String authCode){
        this.authCode=authCode;
    }

    public void setAliAuthBack(AliAuthBack back){
        this.mAliAuthBack=back;
    }

    public interface AliAuthBack{
        void authInfo(String authCode,String userId);
    }
    public static void WechatAuth(Context context){
        final IWXAPI api= WXAPIFactory.createWXAPI(context,null);
        api.registerApp(Const.WeChat_APPID);
        if(!api.isWXAppInstalled()){
            ToastUtil.show("请您先安装微信");
        }else {
            final SendAuth.Req req=new SendAuth.Req();
            req.scope="snsapi_userinfo";
            req.state="wechat_sdk_demo_test";
            api.sendReq(req);
        }
    }
}

支付宝:
1、判断是否安装支付宝 2、发送授权请求 这里必须要异步处理 3、支付宝返回的用户信息 这里利用回调AliAuthBack.authInfo() 将信息返回给Activity;
项目中定义了对象AuthResult用于接受支付宝的返回信息;

AuthResult 代码:

public class AuthResult {
    private String resultStatus;
    private String result;
    private String memo;
    private String resultCode;
    private String authCode;
    private String alipayOpenId;
    private String userId;

    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;
            }
            if (value.startsWith("user_id")) {
                userId = removeBrackets(getValue("user_id=", 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;
    }
    /**
     * @return the userId
     */
    public String getUserId() {
        return userId;
    }
}

微信:
1、判断是否安装微信 2、发送授权请求 3、用户操作后回调WXEntryActivity的onResp方法。

类WXEntryActivity代码如下:
基本时按照官方demo做了一点修改
其中 Const.WeChat_APPID,Const.WeChat_APP_SECRET 就是微信分配的 APPID和AppSecret
这些信息最好是通过服务端获取,在客户端会有安全问题。

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    private IWXAPI api;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.entry);
        api = WXAPIFactory.createWXAPI(this, Const.WeChat_APPID, false);//微信的appId

        try {
            api.handleIntent(getIntent(), this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        setIntent(intent);
        api.handleIntent(intent, this);
        finish();
    }

    //微信发送请求到第三方应用时,会回调到该方法
    @Override
    public void onReq(BaseReq req) {
        switch (req.getType()) {
            case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
                goToGetMsg();
                break;
            case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
                goToShowMsg((ShowMessageFromWX.Req) req);
                break;
            default:
                break;
        }
    }

    //第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
    @Override
    public void onResp(BaseResp resp) {
        int result = 0;

        //Toast.makeText(this, "baseresp.getType = " + resp.getType(), Toast.LENGTH_SHORT).show();

        switch (resp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                result = R.string.errcode_success;
                //微信分享
                if (resp.getType() == ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX)
                    this.finish();
                else{
                    String code = ((SendAuth.Resp) resp).code;
                    //获取用户信息
                    getAccessToken(code);
                }
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = R.string.errcode_cancel;
                this.finish();
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = R.string.errcode_deny;
                break;
            case BaseResp.ErrCode.ERR_UNSUPPORT:
                result = R.string.errcode_unsupported;
                break;
            default:
                result = R.string.errcode_unknown;
                break;
        }
        Toast.makeText(this, result, Toast.LENGTH_LONG).show();

    }

    private void goToGetMsg() {
    }

    private void goToShowMsg(ShowMessageFromWX.Req showReq) {
    }

    private void getAccessToken(String code) {
        //获取授权
        StringBuffer loginUrl = new StringBuffer();
        loginUrl.append("https://api.weixin.qq.com/sns/oauth2/access_token")
                .append("?appid=")
                .append(Const.WeChat_APPID)
                .append("&secret=")
                .append(Const.WeChat_APP_SECRET)
                .append("&code=")
                .append(code)
                .append("&grant_type=authorization_code");
        OkHttpUtils.ResultCallback<String> resultCallback = new OkHttpUtils.ResultCallback<String>() {
            @Override
            public void onSuccess(String response) {
                String access = null;
                String openId = null;
                try {
                    JSONObject jsonObject = new JSONObject(response);
                    access = jsonObject.getString("access_token");
                    openId = jsonObject.getString("openid");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //获取个人信息
                String getUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access + "&openid=" + openId;
                OkHttpUtils.ResultCallback<String> reCallback = new OkHttpUtils.ResultCallback<String>() {
                    @Override
                    public void onSuccess(String response) {
                        String nickName = null;
                        String sex = null;
                        String city = null;
                        String province = null;
                        String country = null;
                        String headimgurl = null;
                        WechatUserInfo info = new WechatUserInfo();
                        try {
                            JSONObject jsonObject = new JSONObject(response);
                            String deviceId= AppBaseApplication.getInstance().getDeviceInfo().deviceId;
                            info.setMemberID(deviceId);
                            info.setOpenId(jsonObject.getString("openid"));
                            info.setNickName(jsonObject.getString("nickname"));
                            info.setSex(jsonObject.getString("sex"));
                            info.setCountry(jsonObject.getString("country"));
                            info.setProvince(jsonObject.getString("province"));
                            info.setCity(jsonObject.getString("city"));
                            info.setHeadimgurl(jsonObject.getString("headimgurl"));
                            info.setUnionid(jsonObject.getString("unionid"));

                            //传到Activity
                            /*Intent i= new Intent(WXEntryActivity.this,PutForwardBindActivity.class);
							i.putExtra("userInfo",info);
							startActivity(i);*/

                            //添加到数据库
                            WechatUserInfoDaoImpl wechatImpl = new WechatUserInfoDaoImpl(HsApplication.getInstance());
                            wechatImpl.insert(info);
                            finish();

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onFailure(Exception e) {
                        ToastUtil.show(WXEntryActivity.this,"获取信息失败");
                        finish();
                    }
                };
                OkHttpUtils.get(getUserInfo.toString(), reCallback);
            }

            @Override
            public void onFailure(Exception e) {
                ToastUtil.show(WXEntryActivity.this,"登录失败");
                finish();
            }
        };
        OkHttpUtils.get(loginUrl.toString(), resultCallback);
    }

}

重点注意onResp这个方法是应用发送到微信的请求处理后的响应结果,会回调到该方法
1、判断 resp.errCode的值 成功会返回并且带上授权临时票据code参数;
2、通过code参数加上AppID和AppSecret等,通过API调用获得access_token;
3、通过access_token进行接口调用,获取用户基本数据信息
这里获取到用户基本信息后我这里存到了本地数据库(使用OrmLite框架,参考https://www.cnblogs.com/itgungnir/p/6210949.html),可以用其他方式返回微信的个人信息。

OkHttpUtils的代码:

public class OkHttpUtils {
    private static OkHttpUtils mInstance;
    private OkHttpClient mOkHttpClient;
    private Handler mDelivery;
    protected static Retrofit mRetrofit;

    private OkHttpUtils() {
        mOkHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .build();
        mDelivery = new Handler(Looper.getMainLooper());

    }

    private synchronized static OkHttpUtils getmInstance() {
        if (mInstance == null) {
            mInstance = new OkHttpUtils();
        }
        return mInstance;
    }

    private void getRequest(String url, final ResultCallback callback) {
        final Request request = new Request.Builder().url(url).build();
        deliveryResult(callback, request);
    }

    private void postRequest(String url, final ResultCallback callback, List<Param> params) {
        Request request = buildPostRequest(url, params);
        deliveryResult(callback, request);
    }

    /**
     * 处理结果
     * @param callback
     * @param request
     */
    private void deliveryResult(final ResultCallback callback, Request request) {

        mOkHttpClient.newCall(request).enqueue(new Callback() {


            @Override
            public void onFailure(Call call, IOException e) {
                sendFailCallback(callback, e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try {
                    String str = response.body().string();
                    if (callback.mType == String.class) {
                        /**
                         * 返回字符串
                         */
                        sendSuccessCallBack(callback, str);
                    } else {
                        /**
                         * 这里处理解析返回对象
                         */
                        Object object = JSON.parseObject(str, callback.mType);
                        sendSuccessCallBack(callback, object);

                    }
                } catch (final Exception e) {
//                    LogUtils.e(TAG, "convert json failure", e);
                    sendFailCallback(callback, e);
                }
            }
        });
    }

    private void sendFailCallback(final ResultCallback callback, final Exception e) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                if (callback != null) {
                    callback.onFailure(e);
                }
            }
        });
    }

    private void sendSuccessCallBack(final ResultCallback callback, final Object obj) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                if (callback != null) {
                    callback.onSuccess(obj);
                }
            }
        });
    }

    private Request buildPostRequest(String url, List<Param> params) {
        FormBody.Builder builder= new FormBody.Builder();
        for (Param param : params) {
            builder.add(param.key, param.value);
        }
        RequestBody requestBody = builder.build();
        return new Request.Builder().url(url).post(requestBody).build();
    }


    /**********************对外接口************************/

    /**
     * get请求
     * @param url  请求url
     * @param callback  请求回调
     */
    public static void get(String url, ResultCallback callback) {
        getmInstance().getRequest(url, callback);
    }

    /**
     * post请求
     * @param url       请求url
     * @param callback  请求回调
     * @param params    请求参数
     */
    public static void post(String url, final ResultCallback callback, List<Param> params) {
        getmInstance().postRequest(url, callback, params);
    }

    /**
     * http请求回调类,回调方法在UI线程中执行
     * @param <T>
     */
    public static abstract class ResultCallback<T> {

        Type mType;

        public ResultCallback(){
            mType = getSuperclassTypeParameter(getClass());
        }

        static Type getSuperclassTypeParameter(Class<?> subclass) {
            Type superclass = subclass.getGenericSuperclass();
            if (superclass instanceof Class) {
                throw new RuntimeException("Missing type parameter.");
            }
            ParameterizedType parameterized = (ParameterizedType) superclass;
            return parameterized.getActualTypeArguments()[0];
        }

        /**
         * 请求成功回调
         * @param response
         */
        public abstract void onSuccess(T response);

        /**
         * 请求失败回调
         * @param e
         */
        public abstract void onFailure(Exception e);
    }

    /**
     * post请求参数类   这里可以根据项目抽取成泛型
     */
    public static class Param {

        String key;
        String value;

        public Param() {
        }

        public Param(String key, String value) {
            this.key = key;
            this.value = value;
        }

    }

}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
微信H5网页授权是指在使用微信浏览器访问H5网页时通过微信授权登录,获取用户的基本信息。这个过程分为三个步骤:引导用户授权获取授权码、通过授权获取用户信息。 首先,用户进入H5网页后,网页需要引导用户进行授权登录。网页可以通过调用微信JS-SDK中的微信授权接口,弹出微信授权登录的窗口。用户点击确认后,微信会生成一个授权码,并跳转回H5网页。 然后,网页需要使用授权码去微信服务器获取用户的基本信息。网页可以通过HTTP请求,将授权码发送给微信服务器的接口,并附上AppID和AppSecret等参数。微信服务器验证授权码的有效性后,会返回用户的基本信息,如openid、昵称、头像等。 最后,网页可以根据获取的用户基本信息,进行相应的业务操作。比如显示用户的头像和昵称,或者根据openid等唯一标识,将用户与其它业务系统进行关联。 需要注意的是,进行微信H5网页授权需要先申请微信开放平台的开发者账号,并创建一个公众号或移动应用。通过在微信开放平台进行配置,获取AppID和AppSecret等必要的参数,用于网页授权的流程中。 总结起来,微信H5网页授权获取用户基本信息是通过使用微信授权接口,引导用户进行授权登录,再通过授权码和微信服务器进行交互,最终获取用户的基本信息。这个过程可以实现在H5网页上使用微信账号登录,并获取用户信息的功能。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值