微信第三方授权登录

    晚上闲来没事,手里突然痒痒的,突然还是写点东西吧,结果想想,不是去年7月份微信刚公开开放第三方app授权登录!结果还是有很多应用纷纷采用这个了,可是实际开发中,并不是如我们想象的那么顺利,看到很多人都在吐槽。今天我就和大家谈谈第三方微信登录。
    微信登录不外乎和微博登录和qq登录本质上还是一样的。
    首先,我们来谈谈微信登录的整体流程:

    首先需要注册微信开放平台,然后获取开发者认证。审批通过之后再创建一个移动应用同样还是需要审批。通过之后就可以给这个应用添加微信授权登陆以及相应功能了。
    1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
    2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
    3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

    那我们要到微信官方开发网站上,进行app注册与授权,获取授权后得到的AppId和AppSecret这两个值。既然谈到了这里,有点一定要注意了,微信在这点上分两种:一种是打包成apk后的注册的AppId和AppSecret,而另一种是开发debug中要注册的AppId和AppSecret.
    第一种倒好,主要是第二种,对于我们开发的人来说,要是不能调试的话那是一件很痛苦的事情。
    [微信开发平台](https://open.weixin.qq.com)
![这里写图片描述](http://img.blog.csdn.net/20150310211907662)
上下载微信签名开发工具到手机上,同时运行的软件也安装到本机上,然后输入包名获取MD5码签名。[签名apk下载地址](http://open.weixin.qq.com/download/sdk/gen_signature.apk)
    注意:如果是Bebug的话,一定要下载地址也用包名。
// WX_APP_ID替换为你的应用从官方网站申请到的合法appId
    public static String WX_APP_ID = "wx147*****00f4b";

    // 自己微信应用的 appSecret
    public static String WX_SECRET = "e79***********252773df78a7e4b";

    public static String WX_CODE = "";

    // IWXAPI 是第三方app和微信通信的openapi接口
    public static IWXAPI wxApi;
    public static boolean isWXLogin = false;

    private wxLogin() {
        context = MyApplication.instance;
        // 通过wxapofactory工厂,获取IWXAPI的实例
        wxApi = WXAPIFactory.createWXAPI(MyApplication.instance, WX_APP_ID,
                true);
        // 将应用的appId注册到微信
        wxApi.registerApp(WX_APP_ID);
    }
    现在我们开始和微信进行通话,在项目代码中新建一个Activity,并提供相应的回调方法供微信调用。
    在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity(例如应用程序的包名为com.lzp.wxlogin。
        <activity  android:name="com.lzp.wxlogin.wxapi.WXEntryActivity" android:configChanges="keyboardHidden|orientation" android:exported="true" android:launchMode="singleTop" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar" />

Android平台应用授权登录接入代码示例(请参考Android接入指南):

{ 
// send oauth request 
Final SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wechat_sdk_demo_test";
api.sendReq(req);
}

appid : 应用唯一标识,在微信开放平台提交应用审核通过后获得
scope : 应用授权作用域,如获取用户个人信息则填写snsapi_userinfo
state : 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

返回说明
用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方。
ErrCode ERR_OK = 0(用户同意)
ERR_AUTH_DENIED = -4(用户拒绝授权)
ERR_USER_CANCEL = -2(用户取消)
code    用户换取access_token的code,仅在ErrCode为0时有效
state   第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K
lang    微信客户端当前语言
country 微信用户当前国家信息

第二步:通过code获取access_token
获取第一步的code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

牢骚了那么多了,估计看的人也醉了,那我添下详细代码:
package com.lzp.wxlogin;

import android.content.Context;

import com.tencent.mm.sdk.modelmsg.SendAuth;
import com.tencent.mm.sdk.modelmsg.SendMessageToWX;
import com.tencent.mm.sdk.modelmsg.WXMediaMessage;
import com.tencent.mm.sdk.modelmsg.WXTextObject;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

/** * @类名:wxLogin * @类描述:微信登录 * @作者:asus * @创建时间:2015年3月7日-下午7:01:35 */
public class wxLogin {
    private Context context;
    public static String text = "";
    public static String WEXIN_SCOPE = "";// 这里填的snsapi_userinfo,用snsapi_base提示没权限。
    public static String WEIXIN_STATE = "";// 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验。

    // WX_APP_ID替换为你的应用从官方网站申请到的合法appId
    public static String WX_APP_ID = "wx147***c00f4b";

    // 自己微信应用的 appSecret
    public static String WX_SECRET = "e791f62cfb9f****52773df78a7e4b";

    public static String WX_CODE = "";

    // IWXAPI 是第三方app和微信通信的openapi接口
    public static IWXAPI wxApi;
    public static boolean isWXLogin = false;

    private wxLogin() {
        context = MyApplication.instance;
        // 通过wxapofactory工厂,获取IWXAPI的实例
        wxApi = WXAPIFactory.createWXAPI(MyApplication.instance, WX_APP_ID,true);
        // 将应用的appId注册到微信
        wxApi.registerApp(WX_APP_ID);
    }

    /* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定的关系,而且只有被调用到时才会装载,从而实现了延迟加载 */
    private static class SingTonHolder {
        /* 静态初始化器,由JVM来保证线程安全 */
        private static wxLogin instance = new wxLogin();
    }

    /* 该单例实现了延迟加载和线程安全 */
    public static wxLogin getInstance() {
        return SingTonHolder.instance;
    }

    /** * @方法说明:微信登录 * @方法名称:wx_Login * @返回值:void */
    public void wx_Login() {
        if (wxApi == null) {
            wxApi = WXAPIFactory.createWXAPI(context, WX_APP_ID, false);
            wxApi.registerApp(WX_APP_ID);
        }

        if (!wxApi.isWXAppInstalled()) {
            // 提醒用户没有按照微信
// Tools.showPrompt("尊敬的用户你好,您手机上未检测到微信,请去安卓应用市场下载安装微信!",
// Tools.ALERT_SHOW);
            return;
        }

        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wechat_sdk_demo_test";
        // sendReq是第三方app主动发送消息给微信,发送完成之后会切回到第三方app界面。
        wxApi.sendReq(req);
    }


    public void setContext(Context context) {
        this.context = context;
    }

    /** * @methods: 获得微信用户信息 */
    // private void loadWXUserInfo() {
    // new Thread(new Runnable() {
    // @Override
    // public void run() {
    // String accessTokenUrl =
    // "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
    // + WX_APP_ID
    // + "&secret="
    // + WX_SECRET
    // + "&code="
    // + WX_CODE + "&grant_type=authorization_code";
    // String tokenResult = ApiClient.httpsGet(accessTokenUrl);
    // if (null != tokenResult) {
    // JSONObject tokenObj;
    // try {
    // tokenObj = new JSONObject(tokenResult);
    // String accessToken = tokenObj.optString("access_token");
    // String openId = tokenObj.optString("openid");
    // String userUrl = "https://api.weixin.qq.com/sns/userinfo?access_token="
    // + accessToken + "&openid=" + openId;
    // String wxUserInfo = ApiClient.httpsGet(userUrl);
    // JSONObject userObj = new JSONObject(wxUserInfo);
    // Tools.showPrompt(wxUserInfo + " :微信: " + userObj,
    // Tools.ALERT_SHOW);
    // } catch (JSONException e) {
    // e.printStackTrace();
    // }
    // }
    // }
    // }).start();
    // isWXLogin = false;
    // }
}
package com.lzp.wxlogin.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import com.lzp.wxlogin.wxLogin;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.modelmsg.SendAuth;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        wxLogin.wxApi.handleIntent(getIntent(), this);
    }

    @Override
    public void onReq(BaseReq req) {
        finish();
    }

    @Override
    public void onResp(BaseResp resp) {
        switch (resp.errCode) {
        case BaseResp.ErrCode.ERR_OK:
            if (wxLogin.isWXLogin) {
            /**jar包不同,这里调用有点区别,我把两者都贴出来**/
                wxLogin.WX_CODE = sendResp.code;
                wxLogin.WX_CODE = sendResp.token;
                /**获得微信用户信息**/
                wxLogin.getInstance().loadWXUserInfo();
                finish();
            } else {
                Toast.makeText(this, "成功!", Toast.LENGTH_LONG).show();
            }
            break;
        case BaseResp.ErrCode.ERR_USER_CANCEL:
            Toast.makeText(this, "取消!", Toast.LENGTH_LONG).show();
            break;
        case BaseResp.ErrCode.ERR_AUTH_DENIED:
            Toast.makeText(this, "被拒绝", Toast.LENGTH_LONG).show();
            break;
        default:
            Toast.makeText(this, "失败!", Toast.LENGTH_LONG).show();
            break;
        }
        wxLogin.isWXLogin = false;
        finish();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        wxLogin.wxApi.handleIntent(intent, this);
        finish();
    }
}

好,写的文采有点纠结了,本来自己慢清晰的思路,自己确实越写越让人看不懂,连我都看不懂了!下次修改改良!不喜勿喷

你可能感兴趣的:(Android开发,登录,微信授权登录,第三方app授权)