由于最近项目需求,需要在app中实现微信授权快速登录,参考学习各位大佬的帖子后终于完成了。现在回头来总结记录一下,如有总结的不到位的,请谅解。

编码前准备工作:开发之前我们需要准备两个东西AppID和AppSecret,需要到微信开放平台(https://open.weixin.qq.com)注册开发者账号,并在移动应用中将我们的APP创建进去,填写对应资料后提交审核。

审核通过之后微信开放平台会为我们生成对应的AppID,以及设置后面需要用到的AppSecret。

审核通过后微信也为我们提供了许多接口,例如微信支付(微信支付需要到微信商户平台https://pay.weixin.qq.com,开通商户账号,具体实现下一篇微信支付再细说)、微信登录;微信登录就是我们需要用到的授权登录。

准备工作做好后我们开始实现,我们项目用的是spring+springBoot+mybatis框架进行的接口开发,嵌入了swagger进行接口管理。

1.第一步是由app端调起微信授权登录页面让用户进行授权操作,用户确认授权后会返回一个code,这个code就是我们后面获取授权用户信息的关键(具体实现见末尾附上的微信开发文档)

2.拿着第一步获得的code去获取用户信息并进行登录操作,下面附上鄙人的代码

controller:

/*** @throws* @title weChatLogin* @description 微信授权登录* @author Kuangzc* @updateTime 2019-9-12 16:00:51*/
@ApiOperation(value = "微信授权登录")
@ApiImplicitParams({@ApiImplicitParam(paramType = "query", name = "code", value = "用户换取access_token的code,仅在ErrCode为0时有效", required = true, dataType = "String")
})
@GetMapping("/weChatLogin")
protected ApiResult weChatLogin(@RequestParam String code) {return appLoginRegisterService.weChatLogin(code);
}

interface:

/*** @throws* @title weChatLogin* @description 微信授权登录* @author Kuangzc* @updateTime 2019-9-12 16:00:51*/
ApiResult weChatLogin(String code);

serviceImpl:

/*** @throws* @title weChatLogin* @description 微信授权登录* @author Kuangzc* @updateTime 2019-9-12 16:00:51*/
public ApiResult weChatLogin(String code) {try {//通过第一步获得的code获取微信授权信息String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + AuthUtil.APPID + "&secret="+ AuthUtil.APPSECRET + "&code=" + code + "&grant_type=authorization_code";JSONObject jsonObject = AuthUtil.doGetJson(url);String openid = jsonObject.getString("openid");String token = jsonObject.getString("access_token");String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openid+ "&lang=zh_CN";JSONObject userInfo = AuthUtil.doGetJson(infoUrl);//成功获取授权,以下部分为业务逻辑处理了,根据个人业务需求写就可以了if (userInfo != null && openid != null) {String nickname = userInfo.getString("nickname");String headimgurl = userInfo.getString("headimgurl");headimgurl = headimgurl.replace("\\", "");//根据openid查询时候有用户信息ResponseMemberDTO memberDTO = appCoreMemberMapper.getMemberInfoByOpenid(openid);if (Objects.isNull(memberDTO)) {//没有绑定用户请前往绑定HashMap map = new HashMap();map.put("state", "1");map.put("openid", openid);map.put("token", "");map.put("nickname", nickname);map.put("photo", headimgurl);return ApiUtil.success("登录成功", map);} else {//已经绑定用户信息直接登录UserInfo userInfos = UserInfo.build(memberDTO.getId().longValue(), memberDTO.getMobile(), new Date(), 1);String Token = tokenManager.setToken(userInfos);// 缓存权限Map<String, String> httpUrl = new HashMap<>();httpUrl.put("kylin", "shuoye.com:8484");authHandler.setRoleUrl(memberDTO.getId().toString(), httpUrl);HashMap map = new HashMap();map.put("state", "2");map.put("openid", openid);map.put("token", Token);return ApiUtil.success("登录成功", map);}} else {return ApiUtil.fail("登录失败");}} catch (Exception e) {return ApiUtil.fail("登录失败");}
}
AuthUtil:
package com.shuoyeah.kylin.common.util;import com.alibaba.fastjson.JSONObject;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;/*** 微信授权登录调用Util*/
public class AuthUtil {public static final String APPID = "***************";//自己的微信APPIDpublic static final String APPSECRET = "***************";//自己的微信APPSECRETpublic static JSONObject doGetJson(String URL) throws IOException {JSONObject jsonObject = null;HttpURLConnection conn = null;InputStream is = null;BufferedReader br = null;StringBuilder result = new StringBuilder();try {//创建远程url连接对象URL url = new URL(URL);//通过远程url连接对象打开一个连接,强转成HTTPURLConnection类conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");//设置连接超时时间和读取超时时间conn.setConnectTimeout(15000);conn.setReadTimeout(60000);conn.setRequestProperty("Accept", "application/json");//发送请求conn.connect();//通过conn取得输入流,并使用Reader读取if (200 == conn.getResponseCode()) {is = conn.getInputStream();br = new BufferedReader(new InputStreamReader(is, "UTF-8"));String line;while ((line = br.readLine()) != null) {result.append(line);System.out.println(line);}} else {System.out.println("ResponseCode is an error code:" + conn.getResponseCode());}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {try {if (br != null) {br.close();}if (is != null) {is.close();}} catch (IOException ioe) {ioe.printStackTrace();}conn.disconnect();}jsonObject = JSONObject.parseObject(result.toString());return jsonObject;}
}

返回的userinfo:

其中包含地址、用户性别、昵称、头像等信息以及唯一的openid,需要注意的是没有手机号码。我们就可以拿着这些信息去进行业务逻辑的实现了。

以上就是我的微信授权登录的实现,如有不到位的地方,敬请谅解,谢谢。

下面附上微信开发文档

准备工作

移动应用微信登录是基于OAuth2.0 协议标准构建的微信 OAuth2.0 授权登录系统。

在进行微信 OAuth2.0 授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的 AppID 和 AppSecret,申请微信登录且通过审核后,可开始接入流程。

1、目前移动应用上微信登录只提供原生的登录方式,需要用户安装微信客户端才能配合使用。2、对于Android应用,建议总是显示微信登录按钮,当用户手机没有安装微信客户端时,请引导用户下载安装微信客户端。3、对于iOS应用,考虑到iOS应用商店审核指南中的相关规定,建议开发者接入微信登录时,先检测用户手机是否已安装微信客户端(使用sdk中isWXAppInstalled函数 ),对未安装的用户隐藏微信登录按钮,只提供其他登录方式(比如手机号注册登录、游客登录等)。

授权流程说明

微信 OAuth2.0 授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信 OAuth2.0 的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过 access_token 可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。

微信 OAuth2.0 授权登录目前支持 authorization_code 模式,适用于拥有 server 端的应用授权。该模式整体流程为:

1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

获取 access_token 时序图:

第一步:请求 CODE

移动应用微信授权登录

开发者需要配合使用微信开放平台提供的 SDK 进行授权登录请求接入。正确接入 SDK 后并拥有相关授权域(scope)权限后,开发者移动应用会在终端本地拉起微信应用进行授权登录,微信用户确认后微信将拉起开发者移动应用,并带上授权临时票据(code)。

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


-(void)sendAuthRequest
{//构造SendAuthReq结构体SendAuthReq* req =[[[SendAuthReq alloc]init]autorelease];req.scope = @"snsapi_userinfo";req.state = @"123";//第三方向微信终端发送一个SendAuthReq消息结构[WXApi sendReq:req];
}

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

{// send oauth requestFinal 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 进行校验

返回示例:

appid: wxd477edab60670232
scope: snsapi_userinfo
state: wechat_sdk_demo

可拉起微信打开授权登录页:

返回说明

用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,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

参数说明

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

返回说明

正确的返回:

{"access_token": "ACCESS_TOKEN","expires_in": 7200,"refresh_token": "REFRESH_TOKEN","openid": "OPENID","scope": "SCOPE","unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数 说明
access_token 接口调用凭证
expires_in access_token 接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新 access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔
unionid 当且仅当该移动应用已获得该用户的 userinfo 授权时,才会出现该字段

错误返回样例:

{"errcode":40029,"errmsg":"invalid code"}

刷新 access_token 有效期

access_token 是调用授权关系接口的调用凭证,由于 access_token 有效期(目前为 2 个小时)较短,当 access_token 超时后,可以使用 refresh_token 进行刷新,access_token 刷新结果有两种:

1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。

refresh_token 拥有较长的有效期(30 天),当 refresh_token 失效的后,需要用户重新授权。

请求方法

获取第一步的 code 后,请求以下链接进行 refresh_token:

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

参数说明

参数 是否必须 说明
appid 应用唯一标识
grant_type 填 refresh_token
refresh_token 填写通过 access_token 获取到的 refresh_token 参数

返回说明

正确的返回:

{"access_token": "ACCESS_TOKEN","expires_in": 7200,"refresh_token": "REFRESH_TOKEN","openid": "OPENID","scope": "SCOPE"
}
参数 说明
access_token 接口调用凭证
expires_in access_token 接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新 access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔

错误返回样例:

{ "errcode": 40030, "errmsg": "invalid refresh_token" }

注意:


1、Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
2、access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;
3、refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。```**建议将Appsecret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。****第三步:通过access_token调用接口**获取access_token后,进行接口调用,有以下前提:1. access_token有效且未超时;
2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。对于接口作用域(scope),能调用的接口有以下:| 授权作用域(scope) | 接口 | 接口说明 |
| --- | --- | --- |
| snsapi_base | /sns/oauth2/access_token | 通过code换取access_token、refresh_token和已授权scope |
| /sns/oauth2/refresh_token | 刷新或续期access_token使用 |
| /sns/auth | 检查access_token有效性 |
| snsapi_userinfo | /sns/userinfo | 获取用户个人信息 |其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。接口调用方法可查阅[微信授权关系接口调用指南](/doc/oplatform/Mobile_App/WeChat_Login/Authorized_API_call_UnionID.html)**F.A.Q****1. 什么是授权临时票据(code)?**答:第三方通过code进行获取access_token的时候需要用到,code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。code的临时性和一次保障了微信授权登录的安全性。第三方可通过使用https和state参数,进一步加强自身授权登录的安全性。**2. 什么是授权作用域(scope)?**答:授权作用域(scope)代表用户授权给第三方的接口权限,第三方应用需要向微信开放平台申请使用相应scope的权限后,使用文档所述方式让用户进行授权,经过用户授权,获取到相应access_token后方可对接口进行调用。**3.开放平台移动应用微信登录目前是否收费?**答:“微信登录”和第三方网站共享微信庞大的用户价值,同时为微信用户提供更便捷服务和更优质内容,实现双向共赢,目前不收取任何费用。

APP调用微信授权登录-JAVA后台实现相关推荐

  1. 支付宝小程序授权登录 (Java 后台篇)

    支付宝小程序授权登录 (Java 后台篇) 开始 : 实现支付宝小程序授权登录功能, 本文主要是介绍支付宝小程序授权登录流程,与关键登录与处理代码. 流程 : 关键代码 : 1.获取用户信息 /*** ...

  2. 微信授权登录(java实现)

    微信公众平台开发文档 微信授权登录获取用户信息有2种方式: 1.静默授权获取用户信息. 2.非静默授权弹出授权界面,用户确认之后获取用户信息(这种方法能够获取到更多信息). 开发前准备: 1.获取到A ...

  3. 微信网页授权登录java后台实现

    建议先阅读微信开发-网页授权登录官方文档: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_au ...

  4. 微信第三方登录——JAVA后台

    小编在此说一声,建议去看一下微信官方提供的流程图,以及其他的之后再看下面的.小编在此就不提供账号申请,那些准备工作了,直接上代码. 微信官方示例→点击打开链接 微信登录流程: 第一步:APP或者网页端 ...

  5. 前端如何调用微信授权登录

    一.开发前必读 1.在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的"开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息"的配置选项中,修 ...

  6. uniapp 中APP使用微信授权登录完整总结

    APP微信授权 主要步骤: (1)在App中要实现微信授权则需要在微信公众平台申请一个应用,获取相应的appid和appsecret: 在填写申请时有2个地方需要注意: 应用包名:是app打包时候可以 ...

  7. 微信公众号 授权登录 JAVA

    微信授权登录 java 首先 腾讯那么大的公司 文档写的那么low 微信那么火 demo写的那么差 我就想说一句  微信简直就是在歧视Java 我这边自己整合了下 微信支付和微信登录 java的代码  ...

  8. ios微信登录不上服务器,iOS微信授权登录

    首先需要确保你的App应用在微信开发平台上注册创建并获得对应的接口,对应登录.支付等功能还涉及付费,具体申请流程就不再这里说了.到开放平台->管理中心->移动应用->查看应用,确认你 ...

  9. 微信鉴权服务器地址,微信开发之微信授权登录

    本篇教程探讨了微信开发之微信授权登录,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入. < 应用场景是:用Hbuilder打包app,在app中点击微信授权登录或者某一操作, ...

  10. wap2app(五)-- 微信授权登录以及踩过的坑

    应用场景是:用Hbuilder打包app,在app中点击微信授权登录或者某一操作,调起微信授权登录,用户授权后拿到用户信息. 一.登录插件配置 先配置微信登录参数 appid和appsecret,在m ...

最新文章

  1. python捷豹_图像处理基本工具——Python 环境下的 Pillow( PIL )
  2. 零基础入门人工智能有门槛吗?学会这些就够了
  3. android老 电池,为什么安卓手机不会因为电池的老化而降频呢?
  4. 图解HTTP笔记(一)
  5. Android_组件的显示与隐藏
  6. raptor五个数排序流程图_看了这篇文章,我发现排序算法好简单
  7. 学生考勤报表管理小程序
  8. matlab两线段的夹角,两条线段的夹角计算
  9. python中flag=1什么意思_001_flag包详解
  10. 大众点评各城市热门餐厅评分字体加密信息数据采集
  11. AndroidAPI
  12. OpenGauss/MogDB调用C FUNCTION 范例
  13. button的setClickable 和 setEnabled 区别
  14. windows找不到文件gpedit.msc怎么办?
  15. 中学教学03教学原则与方法 04教学组织形式05教学评价
  16. 恶劣天气中如何拍摄360全景图片?
  17. Makefile中的死循环问题--学习李云《驾驭Makefile》中的疑惑解决
  18. 计算机考研面试自我介绍范文英语,研究生复试英文自我介绍范文
  19. windows8下linux deepin双系统安装,记录一次Windows+Deepin双系统安装及简单优化
  20. scrapy 常见问题集锦

热门文章

  1. 图片去水印的原理_去水印简单操作:图图去水印
  2. android手表微信运动,华为手表(华为运动健康APP)终于能绑定微信运动
  3. 组网[ZeroTier]+自建Moon服务
  4. 计算机系军训口号四句霸气,军训口号四句霸气中队
  5. 解决JSON页面乱码
  6. A(AI)、B(BigData)、C(Cloud)通俗介绍
  7. 小学生“快乐读书吧”具体要求以及推荐书目集
  8. 编译错误(拓补排序)
  9. Windows下使用Git+rsync构建文件同步工具
  10. 台式机和笔记本快速互拷超大文件