微信授权登录

1,799 阅读10分钟
原文链接: blog.csdn.net

    微信授权登录步骤及账号部分在微信相关功能中体现,此处不再赘述:微信相关功能

    账号注册号之后创建APP基本信息,APP信息,注意包名与签名填写必须正确。

    下面进入功能集成部分

 1、资源集成,两种方式:

    1)下载资源集成(已经不再推荐,最新的下载链接连接到的是Jcenter)。

    地址:微信资源下载

    下载之后解压得到  libammsdk.jar集成到项目中并进行依赖即可

    2)gradle方式集成。

[html] view plain copy print?
  1. dependencies {  
  2.     compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'  
  3. }  
dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}

或者

[html] view plain copy print ?
  1. dependencies {  
  2.     compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'  
  3. }  
dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}

第一个包含统计功能,第二个不包含统计功能。

2、权限注册:

    在Manifests进行相关的权限注册如下:

[html] view plain copy print?
  1. <uses-permission android:name="android.permission.INTERNET" />  
  2.   
  3. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
  4.   
  5. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
  6.   
  7. <uses-permission android:name="android.permission.READ_PHONE_STATE" />  
  8.   
  9. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
<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"/>

3、将APP注册到微信(注意将appId替换成你自己注册的AppId):

[java] view plain copy print?
  1. IWXAPI weixinAPI=WXAPIFactory.createWXAPI(this, 'appiId', true);  
  2. weixinAPI.registerApp('appId');  
IWXAPI weixinAPI=WXAPIFactory.createWXAPI(this, 'appiId', true);
weixinAPI.registerApp('appId');

4、微信授权请求(返回code):

      微信登录只支持安装客户端之后进行授权,所以需要先检测是否安装了微信再分情情况进行相关的处理,WeixinAPI对象就用上述步骤3中初始化的对象即可。

[java] view plain copy print?
  1. if (PigeonApp.WeixinAPI.isWXAppInstalled()) {  
  2.           final SendAuth.Req req = new SendAuth.Req();  
  3.           req.scope = "snsapi_userinfo";  
  4.           req.state = "wechat_sdk_pigeon_racing";  
  5.           PigeonApp.WeixinAPI.sendReq(req);  
  6.           ToastUtils.getInstance(mContext).showToast("正在进行微信登录,请稍后...", false);  
  7.       } else {  
  8.           ToastUtils.getInstance(mContext).showToast("请先安装微信客户端", false);  
  9.       }  
  if (PigeonApp.WeixinAPI.isWXAppInstalled()) {
            final SendAuth.Req req = new SendAuth.Req();
            req.scope = "snsapi_userinfo";
            req.state = "wechat_sdk_pigeon_racing";
            PigeonApp.WeixinAPI.sendReq(req);
            ToastUtils.getInstance(mContext).showToast("正在进行微信登录,请稍后...", false);
        } else {
            ToastUtils.getInstance(mContext).showToast("请先安装微信客户端", false);
        }

授权请求需要三个参数,分别为:

appid 是 应用唯一标识,在微信开放平台提交应用审核通过后获得
scope 是 应用授权作用域,如获取用户个人信息则填写snsapi_userinfo

state 否 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验(其实就是一个校验码,自己写一个字符串就可以了)。

5、微信授权回调的Activity,内容如下(由于此处是分享和授权都有,所以首先判断类型再进行分情况处理,Activity名称必须为WXEntryActivity,注意在Manifests中注册Activity):

[java] view plain copy print?
  1. import android.app.Activity;  
  2. import android.content.Intent;  
  3. import android.os.Bundle;  
  4. import android.text.TextUtils;  
  5.   
  6. import com.google.gson.Gson;  
  7. import com.orhanobut.logger.Logger;  
  8. import com.tencent.mm.sdk.constants.ConstantsAPI;  
  9. import com.tencent.mm.sdk.modelbase.BaseReq;  
  10. import com.tencent.mm.sdk.modelbase.BaseResp;  
  11. import com.tencent.mm.sdk.modelmsg.SendAuth;  
  12. import com.tencent.mm.sdk.modelmsg.SendMessageToWX;  
  13. import com.tencent.mm.sdk.modelpay.PayResp;  
  14. import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;  
  15.   
  16. import com.zhy.http.okhttp.OkHttpUtils;  
  17. import com.zhy.http.okhttp.callback.StringCallback;  
  18. import com.zhy.http.okhttp.https.HttpsUtils;  
  19. import com.zhy.http.okhttp.request.RequestCall;  
  20.   
  21. import org.json.JSONObject;  
  22.   
  23. import java.io.IOException;  
  24.   
  25. import javax.net.ssl.SSLSocketFactory;  
  26.   
  27. import okhttp3.Call;  
  28. import okhttp3.OkHttpClient;  
  29.   
  30. public class WXEntryActivity extends Activity  implements IWXAPIEventHandler {  
  31.   
  32.     @Override  
  33.     protected void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         PigeonApp.WeixinAPI.handleIntent(getIntent(), this);  
  36.     }  
  37.   
  38.     @Override  
  39.     public void onReq(BaseReq baseReq) {  
  40.   
  41.     }  
  42.   
  43.     @Override  
  44.     public void onResp(BaseResp baseResp) {  
  45.         String result = "";  
  46.         if (baseResp instanceof SendAuth.Resp){//登录授权回调  
  47.             switch (baseResp.errCode) {  
  48.                 case BaseResp.ErrCode.ERR_OK:  
  49.                     SendAuth.Resp resp = (SendAuth.Resp) baseResp;  
  50.                     //发送相关消息  在相关的页面接受                
  51.                     result = "授权成功";  
  52.                     break;  
  53.                 case BaseResp.ErrCode.ERR_USER_CANCEL:  
  54.                     result = "授权取消";  
  55.                     break;  
  56.                 case BaseResp.ErrCode.ERR_AUTH_DENIED:  
  57.                     result = "授权被拒绝";  
  58.                     break;  
  59.                 default:  
  60.                     result = "授权返回";  
  61.                     break;  
  62.             }  
  63.         }else if (baseResp instanceof SendMessageToWX.Resp){ //分享  
  64.             switch (baseResp.errCode) {  
  65.                 case BaseResp.ErrCode.ERR_OK:  
  66.                     result = "分享成功";  
  67. //                    commitScore();  
  68.                     break;  
  69.                 case BaseResp.ErrCode.ERR_USER_CANCEL:  
  70.                     result = "分享取消";  
  71.                     break;  
  72.                 case BaseResp.ErrCode.ERR_AUTH_DENIED:  
  73.                     result = "分享被拒绝";  
  74.                     break;  
  75.                 default:  
  76.                     result = "分享返回";  
  77.                     break;  
  78.             }  
  79.         }  
  80.         finish();  
  81.     }  
  82.     @Override  
  83.     protected void onActivityResult(int requestCode,  int resultCode, Intent data) {  
  84.         super.onActivityResult(requestCode, resultCode, data);  
  85.     }  
  86. }  
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.orhanobut.logger.Logger;
import com.tencent.mm.sdk.constants.ConstantsAPI;
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.modelmsg.SendMessageToWX;
import com.tencent.mm.sdk.modelpay.PayResp;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;

import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import com.zhy.http.okhttp.https.HttpsUtils;
import com.zhy.http.okhttp.request.RequestCall;

import org.json.JSONObject;

import java.io.IOException;

import javax.net.ssl.SSLSocketFactory;

import okhttp3.Call;
import okhttp3.OkHttpClient;

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PigeonApp.WeixinAPI.handleIntent(getIntent(), this);
    }

    @Override
    public void onReq(BaseReq baseReq) {

    }

    @Override
    public void onResp(BaseResp baseResp) {
        String result = "";
        if (baseResp instanceof SendAuth.Resp){//登录授权回调
            switch (baseResp.errCode) {
                case BaseResp.ErrCode.ERR_OK:
                    SendAuth.Resp resp = (SendAuth.Resp) baseResp;
                    //发送相关消息  在相关的页面接受              
                    result = "授权成功";
                    break;
                case BaseResp.ErrCode.ERR_USER_CANCEL:
                    result = "授权取消";
                    break;
                case BaseResp.ErrCode.ERR_AUTH_DENIED:
                    result = "授权被拒绝";
                    break;
                default:
                    result = "授权返回";
                    break;
            }
        }else if (baseResp instanceof SendMessageToWX.Resp){//分享
            switch (baseResp.errCode) {
                case BaseResp.ErrCode.ERR_OK:
                    result = "分享成功";
//                    commitScore();
                    break;
                case BaseResp.ErrCode.ERR_USER_CANCEL:
                    result = "分享取消";
                    break;
                case BaseResp.ErrCode.ERR_AUTH_DENIED:
                    result = "分享被拒绝";
                    break;
                default:
                    result = "分享返回";
                    break;
            }
        }
        finish();
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }
}
[html] view plain copy print ?
  1. <activity  
  2.       android:name=".wxapi.WXEntryActivity"  
  3.       android:exported="true"  
  4.       android:launchMode="singleTop"  
  5.       android:label="@string/app_name"/>  
      <activity
            android:name=".wxapi.WXEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:label="@string/app_name"/>

返回的参数如下:

ErrCode ERR_OK = 0(用户同意) ERR_AUTH_DENIED = -4(用户拒绝授权) ERR_USER_CANCEL = -2(用户取消)
code 用户换取access_token的code,仅在ErrCode为0时有效
state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K
lang 微信客户端当前语言

country 微信用户当前国家信息

6、获取接口调用凭证access_token(详细说明):

接口url:

[java] view plain copy print?
  1. https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code  
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

参数:

appid 是 应用唯一标识,在微信开放平台提交应用审核通过后获得
secret 是 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code 是 填写第一步获取的code参数
grant_type 是 填authorization_code

 返回:

access_token 接口调用凭证
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔

unionid 当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段

正确示例:

[java] view plain copy print?
  1. {   
  2. "access_token":"ACCESS_TOKEN",   
  3. "expires_in":7200,   
  4. "refresh_token":"REFRESH_TOKEN",  
  5. "openid":"OPENID",   
  6. "scope":"SCOPE",  
  7. "unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"  
  8. }  
{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

7、通过access_token调用接口获取自己需要的信息进行业务处理:

接口url:

[html] view plain copy print?
  1. https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid= OPENID  
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

参数:

access_token 是 调用接口凭证

openid         是 普通用户标识,对该公众帐号唯一

lang 否 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN

返回:

参数 说明
openid 普通用户的标识,对当前开发者帐号唯一
nickname 普通用户昵称
sex 普通用户性别,1为男性,2为女性
province 普通用户个人资料填写的省份
city 普通用户个人资料填写的城市
country 国家,如中国为CN
headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。

正确示例:

[html] view plain copy print?
  1. {  
  2. "openid":"OPENID",  
  3. "nickname":"NICKNAME",  
  4. "sex":1,  
  5. "province":"PROVINCE",  
  6. "city":"CITY",  
  7. "country":"COUNTRY",  
  8. "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",  
  9. "privilege":[  
  10. "PRIVILEGE1",  
  11. "PRIVILEGE2"  
  12. ],  
  13. "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"  
  14. }  
{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

建议最好保存unionID信息,以便以后在不同应用之间进行用户信息互通,比如网页登录,APP登录同时存在时候就必须保存unionID,因为同一个用户采用两种方式登录的时候openid可能不同。

完成!