微信第三方登录Android实现代码

记录一下微信第三方实现登录的方法。还是比较简单。

一、必要的准备工作

1.首先需要注册并被审核通过的微信开放平台帐号,然后创建一个移动应用,也需要被审核;

2.然后到资源中心下载开发微信所需的工具;

下载的网址:点击打开链接,有一个是SDK,一个是签名生成工具还有一个范例代码。

3.将SDK文件夹lib下的jar文件libammsdk.jar导入到项目工程中;

4.你的测试手机需要装好微信客户端;

5.在项目的AndroidManifest.xml文件中添加如下的权限:

<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"/>

6.因为微信登录后会返回结果到我们自己的应用,因此,我们需要按如下的规则来建立一个可供回调的Activity

a. 在包名(申请移动应用时所填的包名)下新建一个名为wxapi的包,然后再在wxapi的包中新增一个WXEntryActivity类,这个类需要继承自Activity。

然后再在这个AndroidManifest.xml文件中,将这个activity的export属性设置为true,如下所示。

 <activity
      android:name=".wxapi.WXEntryActivity"
      android:label="@string/title_activity_wxlogin"
      android:launchMode="singleTop"
      android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>

b. 实现IWXAPIEventHandler接口,微信发送的请求将回调到onReq方法,发送到微信请求的响应结果将回调到onResp方法

c. 在WXEntryActivity中将接收到的intent及实现了IWXAPIEventHandler接口的对象传递给IWXAPI接口的handleIntent方法,如下所示

api.handleIntent(getIntent(), this); 

7.微信认证的时序图

这里有一点要注意,就是从上往下数第6个箭头,即通过code加上appid和appsecret换取access_token,其实这一步是在第三方应用服务器上做的,因为appsecret和access_token直接存储于客户端是非常不安全的。Android客户端获取code后,把这个code提交给应用服务器,应用服务器上保存有appsecret信息,由应用服务器来获取access_token,并用access_token来完成其它工作。

二、Android代码

在上一步添加的WXEntryActivity对应的类文件中添加必要的代码,我的代码如下:

package com.example.justyoung.logintest.wxapi; 

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast; 

import com.example.justyoung.logintest.HttpsHelper;
import com.example.justyoung.logintest.R;
import com.example.justyoung.logintest.fileExplorer.WXConstant;
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.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory; 

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID; 

public class WXEntryActivity extends ActionBarActivity implements IWXAPIEventHandler{ 

  private Button wxLogin;
  private IWXAPI api;
  private static String uuid; 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_wxlogin);
    wxLogin = (Button) findViewById(R.id.wx_login_button);
    wxLogin.setOnClickListener(new WXLoginEvent());
    api = WXAPIFactory.createWXAPI(this, WXConstant.APPID);
    api.registerApp(WXConstant.APPID);
    api.handleIntent(getIntent(), this);
  } 

  @Override
  public void onReq(BaseReq baseReq) { 

  } 

  @Override
  public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    api.handleIntent(intent, this);
  } 

  @Override
  public void onResp(BaseResp resp) {
    String result;
    switch (resp.errCode) {
      case BaseResp.ErrCode.ERR_OK:
        result = "OK";
        SendAuth.Resp regResp = (SendAuth.Resp)resp;
        if (!regResp.state.equals(uuid))
          return;
        String code = regResp.code;
        new WXLoginThread("https://192.168.2.133:8443/CloudStorageServer/wechat/login?code=" + code).start();
        break;
      case BaseResp.ErrCode.ERR_USER_CANCEL:
        result = "USER_CANCEL";
        break;
      case BaseResp.ErrCode.ERR_AUTH_DENIED:
        result = "ERR_AUTH_DENIED";
        break;
      default:
        result = "errcode_unknown";
        break;
    } 

    Toast.makeText(this, result, Toast.LENGTH_LONG).show(); 

  } 

  class WXLoginEvent implements View.OnClickListener {
    @Override
    public void onClick(View v) {
      uuid = UUID.randomUUID().toString();
      final SendAuth.Req req = new SendAuth.Req();
      req.scope = "snsapi_userinfo";
      req.state = uuid;
      api.sendReq(req);
    }
  } 

  private class WXLoginThread extends Thread {
    private String url; 

    public WXLoginThread(String url) {
      this.url = url;
    } 

    @Override
    public void run() {
      HttpsHelper httpsHelper = new HttpsHelper();
      try {
        httpsHelper.prepareHttpsConnection(url);
        String response = httpsHelper.connect();
      } catch (KeyManagementException e) {
        e.printStackTrace();
      } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}

代码中的如下片段是用来拉起微信认证界面的。这里我使用了uuid来作为state参数,(该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验)。

uuid = UUID.randomUUID().toString();
final SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = uuid;
api.sendReq(req); 

在用户接受认证后,微信应用会回调IWXAPIEventHandler接口的onResp方法。在该方法中,首先判断返回的resp的状态,若是正常状态,则判断state,然后从再从resp中获取code值。至此客户端便完成了它的工作。

因为客户端保留appsecret和access_token是非常不安全的,因此剩余信息的获取应放到我们的应用服务器上进行。

三、应用服务器代码

在Anroid客户端获取到code后,可提交到我们自己的应用服务器,在我们的应用服务器再通过code,来获取access_token,openid等用户信息。

1.通过code获取access_token,openid的方法是使用GET请求,按以下方式请求微信接口:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

2.通过access_token获取用户的一些信息的方式是通过GET请求使用微信的接口:

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

下面贴一下我自己使用的代码:

private void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String code = getParameter(request, "code");
    if (isArgumentNullOrEmpty(code)) {
      Log.logger.info("code为空");
      return;
    }
    Log.logger.info("收到code: " + code);
    try {
      AccessToken accessToken = new AccessToken("/sns/oauth2/access_token", "authorization_code", code);
      AccessToken.UserData userData = accessToken.getMetaData().getUserInfo();
      ... // userData中就是我们通过access_token获取的用户信息了。
    } catch (WeiXinException e) {
      Log.logException(e);
      writeMessage(response, e.getMessage());
      return;
    } catch (Exception e) {
      Log.logException(e);
      writeMessage(response, "login error");
      return;
    }
  } 
package com.cyber_space.thirdparty.weixin; 

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URI;
import java.net.URISyntaxException; 

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; 

import com.cyber_space.util.JsonUtil; 

public class AccessToken { 

  CloseableHttpClient httpClient;
  HttpGet httpGet;
  URI uri;
  String code; 

  /**
   * 用于公众号
   *
   * @throws URISyntaxException
   */
  public AccessToken() throws URISyntaxException { 

    uri = new URIBuilder().setScheme("https").setHost("api.weixin.qq.com").setPath("/cgi-bin/token")
        .setParameter("grant_type", "client_credential").setParameter("appid", WeiXinConfig.APP_ID)
        .setParameter("secret", WeiXinConfig.APP_SECRET).build();
    httpClient = HttpClients.createDefault();
    httpGet = new HttpGet(uri);
  } 

  public AccessToken(String path, String grantType, String code) throws URISyntaxException {
    uri = new URIBuilder().setScheme("https").setHost("api.weixin.qq.com").setPath(path)
        .setParameter("grant_type", grantType).setParameter("appid", WeiXinConfig.APP_ID)
        .setParameter("secret", WeiXinConfig.APP_SECRET).setParameter("code", code).build();
    httpClient = HttpClients.createDefault();
    httpGet = new HttpGet(uri);
  } 

  public String getAccessToken() throws ClientProtocolException, IOException {
    CloseableHttpResponse response = null;
    try {
      response = httpClient.execute(httpGet);
      HttpEntity httpEntity = response.getEntity();
      if (httpEntity == null)
        return null;
      httpEntity = new BufferedHttpEntity(httpEntity);
      String returnString = EntityUtils.toString(httpEntity);
      String accessToken = com.cyber_space.util.JsonUtil.getAttribute(returnString, "access_token");
      return accessToken;
    } finally {
      response.close();
    }
  } 

  /**
   * 获得用户的元数据信息,只包括openid和access_token
   *
   * @return
   * @throws ClientProtocolException
   * @throws IOException
   * @throws WeiXinException
   */
  public UserData getMetaData() throws ClientProtocolException, IOException, WeiXinException {
    CloseableHttpResponse response = null;
    try {
      response = httpClient.execute(httpGet);
      HttpEntity httpEntity = response.getEntity();
      if (httpEntity == null)
        return null;
      httpEntity = new BufferedHttpEntity(httpEntity);
      String returnString = EntityUtils.toString(httpEntity);
      JsonUtil jUtil = new JsonUtil(returnString, JsonUtil.JSONOBJECT);
      String error = null;
      try {
        error = jUtil.getAttribute("errcode");
      } catch (Exception e) {
      }
      if (error != null && !error.equals("")) {
        throw new WeiXinException(WeiXinException.INVALID_OPENID);
      }
      String openid = jUtil.getAttribute("openid");
      String accessToken = jUtil.getAttribute("access_token");
      UserData uData = new UserData(openid, accessToken);
      return uData;
    } finally {
      response.close();
    }
  } 

  public class UserData {
    public String openid;
    public String accessToken;
    public String nickname;
    public String sex;
    public String province;
    public String city;
    public String country;
    public String headimgurl;
    public String privilege;
    public String unionid; 

    public UserData(String openid, String accessToken) {
      this.openid = openid;
      this.accessToken = accessToken;
    } 

    public UserData getUserInfo()
        throws IOException, IllegalArgumentException, IllegalAccessException, URISyntaxException, WeiXinException {
      URI uri = new URIBuilder().setScheme("https").setHost("api.weixin.qq.com").setPath("/sns/userinfo")
          .setParameter("access_token", this.accessToken).setParameter("openid", this.openid).build();
      HttpGet httpGet = new HttpGet(uri);
      CloseableHttpResponse response = null;
      try {
        response = httpClient.execute(httpGet);
        HttpEntity httpEntity = response.getEntity();
        if (httpEntity == null)
          throw null;
        httpEntity = new BufferedHttpEntity(httpEntity);
        String jsonString = EntityUtils.toString(httpEntity);
        JsonUtil jUtil = new JsonUtil(jsonString, JsonUtil.JSONOBJECT);
        String errcode = null;
        try {
          errcode = jUtil.getAttribute("errcode");
        } catch (Exception e) {
        }
        // 通过反射循环赋值
        if (errcode == null || errcode.equals("")) {
          for (Field i : getClass().getFields()) {
            if (!i.getName().equals("accessToken"))
              i.set(this, jUtil.getAttribute(i.getName()));
          }
          return this;
        }
        else {
          throw new WeiXinException(WeiXinException.INVALID_ACCESSTOKEN);
        }
      } finally {
        response.close();
      }
    }
  } 

} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现第三方登录的上拉展开,下拉隐藏,下拉隐藏示例

    Android的UI和交互是很重要的一部分,直接影响到用户对软件的体验.随着项目经验的积累,发现Android中动画的运用越来越重要.本篇文章抽出了项目登录界面中实现的第三方登录,用户可以上拉展开,下拉隐藏第三方登录这么一个效果,提高用户和软件的交互性. 实现效果: (1)activity_main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&q

  • Android第三方登录之QQ登录

    本文实例为大家分享了Android第三方登录之QQ的具体代码,供大家参考,具体内容如下 第三方登录之QQ 代码区 public class MainActivity extends AppCompatActivity { private Button btn; private TextView tv; private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCr

  • Android实现使用微信登录第三方APP的方法

    本文实例讲述了Android实现使用微信登录第三方APP的方法.分享给大家供大家参考,具体如下: 使用微信登录APP,免去注册过程,现在已经有很多的类似应用了.集成该功能过程不复杂,但还是有一些地方需要注意的. 开始之前,需要做下面的准备工作. 1.到微信开放平台注册你的APP,并申请开通微信登录的权限.参考这里: https://open.weixin.qq.com// 2.下载Android SDK和签名查看工具,请参考: https://open.weixin.qq.com/cgi-bin

  • Android实现第三方授权登录、分享以及获取用户资料

    由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字和图片等这样的效果,几经波折,查阅了一番资料,做了一个Demo.实现起来的效果还是不错的,不敢独享,决定写一个总结的教程,供大家互相交流.学习和参考,只求能和大家共同进步.希望能多多支持! 这篇文章中,我们使用到了Share SDK,它是为iOS.Android.WP8的APP提供社会化功能的一个组件,目前支持如QQ.微信.新浪微博.腾讯微博.开心网.人人网.豆瓣.网易微博.搜狐微博.facebook.twitter.google+

  • Android调用第三方QQ登录代码分享

    本文为大家分享了调用QQ登录的相关代码,希望对大家有帮助,减少项目开发的时间,具体内容如下 1.去QQ开放平台注册帐号(http://open.qq.com/),为应用申请QQ的APP_ID , 并下载相关的jar包,放到工程的lib目录下. 2.在Manifest.xml里注册QQ相关的Activity,代码如下 <activity android:name="com.tencent.connect.common.AssistActivity" android:screenOr

  • Android集成新浪微博第三方登录的方法

    本文实例讲述了Android集成新浪微博第三方登录的方法.分享给大家供大家参考.具体实现方法如下: 1.下载微博的sdk ,导入微博的jar包两个 android-support-v4.jar和weibosdkcore.jar两个包 2.把新浪微博中的demo_src中SDK中的com,导入到项目中 3.用demo中的constants,主要是参数设置,将里面的参数改成自己的参数. 4.编写代码,主要步骤如下: 复制代码 代码如下: // 初始化微博对象 mWeiboAuth = new Wei

  • Android 第三方登录、分享(ShareSDK、友盟)

    为下边的项目做准备,写一个第三方登录.分享的demo.分别使用sharesdk和友盟来实现. 先说一下我对两者的使用上的感觉,个人感觉sharesdk比友盟更好一点,好在哪里呢?好在人工服务上.在集成的过程中遇到了各种问题,但是sharesdk的人工服务做的很好,能给答疑解惑,提供解决问题的方法! 接下来上代码(本文使用android studio开发,sharesdk版本v2.7.7,友盟版本v6.0.0): 一.使用sharesdk(sharesdk版本v2.7.7)来集成: 1.要去官网:

  • Android第三方登录之腾讯QQ登录的实例代码

    布局文件 <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登录成功" android:textSize="25sp" android:layout_marginTop="100dp" /> 清单文件中的配置 <activity android:n

  • Android微信第三方登录(个人笔记)

    今天在写微信登录,花了半天时间搞定.然后写下自己的笔记,希望帮助更多的人.欢迎各位指教. 微信授权登录,官方说的不是很清楚.所以导致有一部分的坑. 微信注册应用平台的应用签名,下载 微信签名生成工具 输入项目的packageName也可以查看到. (注意:debug.Release 一定要区分,因为2种生成的微信签名不一致,会导致没有跳转.回调....一般在微信开发者上面注册的是正式环境打包好的.) 申请微信开发者账号.应用申请省略. 1. AndroidManifest.xml 权限 <!--

  • 微信第三方登录Android实现代码

    记录一下微信第三方实现登录的方法.还是比较简单. 一.必要的准备工作 1.首先需要注册并被审核通过的微信开放平台帐号,然后创建一个移动应用,也需要被审核: 2.然后到资源中心下载开发微信所需的工具: 下载的网址:点击打开链接,有一个是SDK,一个是签名生成工具还有一个范例代码. 3.将SDK文件夹lib下的jar文件libammsdk.jar导入到项目工程中: 4.你的测试手机需要装好微信客户端: 5.在项目的AndroidManifest.xml文件中添加如下的权限: <uses-permis

  • iOS微信第三方登录实现

    一.接入微信第三方登录准备工作. 移动应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统. 在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程.(注意) 1.下载iOS微信SDK. 下载地址 2.将SDK放到工程目录中. 3.补充导入一些依赖框架. 4.添加URL Types 5.添加iOS9 URL Schemes. 注意:如

  • iOS微信第三方登录实例

    本文实例为大家分享了iOS微信第三方登录,供大家参考,具体内容如下 一.准备工作 1.到微信开放平台注册成开发者,获取appid 2.导入WeChatConnection.framework 3.配置URL Schemes  输入appid  例如wx29ce0f21ea982cb8 二.配置AppDelegate.m 1. 注册微信 //微信登陆 [WXApi registerApp:WeiXin_AppId withDescription:@"weixin"]; 2.设置函数 //

  • 微信第三方登录(原生)demo【必看篇】

    在一家ecstore二开公司有一段时间了,公司希望往自己研发产品上面走,一直在培养新人. 最近要自己去微信登录,自己就在ectore的框架基础上,写的原生微信第三方登录以此来熟悉微信第三方登录,在ecstore上面去写. 一个简单的demo,不是很好,分享给大家,希望能给想做微信第三方登录的朋友带来思路... 首先: 资料准备: 水印图片 28*28 png格式 公司logo 高清图片 108*108 png格式 公司logo 1.在微信开放平台 https://open.weixin.qq.c

  • laravel5实现微信第三方登录功能

    背景 最近手头一个项目需要实现用户在网站的第三方登录(微信和微博),后端框架laravel5.4. 实现过程以微信网页版第三方登录,其他于此类似,在此不做重复. 准备工作 网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统. 在进行微信OAuth2.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程. 总结下来就是: 1.进

  • Vue实现Google第三方登录的示例代码

    目录 一.开发者平台配置 解决问题BUG 一.开发者平台配置 1.进入开发者平台,首先前往Google API 控制台选择或者创建一个项目 谷歌开发者平台 一堆眼花缭乱的API让你无从选择,但是你只要记住这次进来的目的是:社交API 2.使用这个API之前还需要做一件事,那就是申请一个OAuth 2.0 客户端 ID 3按照要求填写你项目的类型.名称以及来源url 注:创建完成之后,页面也有一个弹窗将你申请的客户端ID已经密钥展示出来,没错这个就是一个生成的过程. 4.安装vue-google-

  • Django中使用第三方登录的示例代码

    OAuth2.0是什么 OAuth的英文全称是Open Authorization,它是一种开放授权协议.OAuth目前共有2个版本,2007年12月的1.0版(之后有一个修正版1.0a)和2010年4月的2.0版,1.0版本存在严重安全漏洞,而2.0版解决了该问题. OAuth简单说就是一种授权的协议,只要授权方和被授权方遵守这个协议去写代码提供服务,那双方就是实现了OAuth模式. OAuth2.0实现第三方登录的流程 例如你想登录豆瓣去看看电影评论,但你丫的从来没注册过豆瓣账号,又不想新注

  • 用django-allauth实现第三方登录的示例代码

    现在我们已经拥有一个可以进行用户本地登录的博客系统了.如果有人欣赏你的文章,说不定就会注册成为本地用户,并和你好好交流一番. 但头疼的是,用户可能每天都在互联网上浏览很多非常棒的博客,如果每个博客都要去注册才能评论,对用户是个不小的负担.对个人博客这类草根网站,说不定用户就懒得去注册了,你也就损失了一个潜在的"粉丝". 比较流行的解决方案是允许用户通过第三方登录,即可以通过GitHub.微博这类知名社区的授权,从而登录你的小站,免去了注册的麻烦. 本章会介绍一个强大的库:Django-

  • Java实现QQ第三方登录的示例代码

    前期准备工作 1.云服务器 2.备案的域名 3.本地调试需要修改hosts文件,将域名映射到127.0.0.1 如何修改hosts文件:https://www.jb51.net/diannaojichu/319774.html 申请QQ互联,并成为开发者 申请QQ互联创建应用时需要备案域名,所以建议提前准备备案域名. QQ互联:https://connect.qq.com/index.html 登录后,点击头像,进入认证页面,填写信息,等待审核. 审核通过后创建应用 应用创建通过审核后,就可以使

随机推荐