微信授权登录功能实现
微信授权登录
- 1、需求描述
- 2、授权登录
- 2.1 配置授权回调域名
- 2.2 部署公众号前端页面
- 2.3 前端处理
- 3、授权登录接口
- 3.1 引入微信工具包
- 3.2 添加配置
- 3.3 添加工具类
- 3.4 Controller
- 3.5 编写UserInfoService
- 3.6 使用token
- 3.6.1 JWT介绍
- 3.6.2 JWT的原理
- 3.6.3 整合JWT
- 3.7 微信授权登录测试
这是根据网上视频做的一个硅谷课堂微服务项目,理由有涉及到微信公众号的开发。
个人用户暂时只能用测试号开发,尤其注意内网穿透那里,昨晚域名没配置好卡在那了,改了半天没改好,白天在看论文没搞这个,晚上突然灵感来了找到了问题的关键,就当bug记录了。
笔记也是参考别人的,我根据自己的代码和配置做了一点小改动。
也可以去看我去年写过的另一篇文章:微信扫码登录实现
1、需求描述
根据流程图通过菜单进入的页面都要授权登录
2、授权登录
接口文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
说明:
1、严格按照接口文档实现;
2、应用授权作用域scope:scope为snsapi_userinfo
2.1 配置授权回调域名
(1)在公众号正式号配置
这个只针对有正式公众号的企业用户,个人用户不用看这一步。
在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“设置与开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头;
本地测试配置内网穿透地址
(2)在公众号测试号配置
将上面的域名经过内网穿透映射到我本地8333端口,也就是我的网关微服务。
2.2 部署公众号前端页面
(1)公众号前端页面已经开发完成,直接部署使用即可
这里我也是用的别人的模板。
(2)启动公众号页面项目
使用命令:npm run serve
2.3 前端处理
(1)全局处理授权登录,处理页面:/src/App.vue
说明1:访问页面时首先判断是否有token信息,如果没有跳转到授权登录接口
说明2:通过localStorage存储token信息
在HTML5中,加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间很小,只有几K),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同。它只能存储字符串格式的数据,所以最好在每次存储时把数据转换成json格式,取出的时候再转换回来。
(2)前端代码实现
wechatLogin() {// 处理微信授权登录let token = this.getQueryString('token') || '';if(token != '') {window.localStorage.setItem('token', token);}// 所有页面都必须登录,两次调整登录,这里与接口返回208状态token = window.localStorage.getItem('token') || '';if (token == '') {let url = window.location.href.replace('#', 'guiguketan')window.location = 'http://glkt.atguigu.cn/api/user/wechat/authorize?returnUrl=' + url}console.log('token2:'+window.localStorage.getItem('token'));},
上面是老师给的示例代码,你需要将上面的
window.location
中的域名glkt.atguigu.cn
改成你用内网穿透工具配置好的。
3、授权登录接口
操作模块:service-user
3.1 引入微信工具包
<dependencies><dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>2.7.0</version></dependency><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.1</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId></dependency>
</dependencies>
3.2 添加配置
#公众号id和秘钥
# 硅谷课堂微信公众平台appId
wechat.mpAppId: wx09f201e9013e81d8
## 硅谷课堂微信公众平台api秘钥
wechat.mpAppSecret: 6c999765c12c51850d28055e8b6e2eda
# 授权回调获取用户信息接口地址
wechat.userInfoUrl: http://ggkt.vipgz1.91tunnel.com/api/user/wechat/userInfo
上面只是个示例,将这三个值改成你自己的。id和密钥见下图
然后上面的回调地址的域名也改成你自己的。
3.3 添加工具类
@Component
public class ConstantPropertiesUtil implements InitializingBean {@Value("${wechat.mpAppId}")private String appid;@Value("${wechat.mpAppSecret}")private String appsecret;public static String ACCESS_KEY_ID;public static String ACCESS_KEY_SECRET;@Overridepublic void afterPropertiesSet() throws Exception {ACCESS_KEY_ID = appid;ACCESS_KEY_SECRET = appsecret;}
}
@Configuration
public class WeChatMpConfig {@Autowiredprivate ConstantPropertiesUtil constantPropertiesUtil;@Beanpublic WxMpService wxMpService(){WxMpService wxMpService = new WxMpServiceImpl();wxMpService.setWxMpConfigStorage(wxMpConfigStorage());return wxMpService;}@Beanpublic WxMpConfigStorage wxMpConfigStorage(){WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage();wxMpConfigStorage.setAppId(ConstantPropertiesUtil.ACCESS_KEY_ID);wxMpConfigStorage.setSecret(ConstantPropertiesUtil.ACCESS_KEY_SECRET);return wxMpConfigStorage;}
}
3.4 Controller
@Slf4j
@Controller
@RequestMapping("/api/user/wechat")
public class WechatController {@Autowiredprivate UserInfoService userInfoService;@Autowiredprivate WxMpService wxMpService;//取出配置文件中的回调地址@Value("${wechat.userInfoUrl}")private String userInfoUrl;//授权跳转@GetMapping("authorize")public String authorize(@RequestParam("returnUrl") String returnUrl,HttpServletRequest request) {String url = wxMpService.oauth2buildAuthorizationUrl(userInfoUrl,WxConsts.OAUTH2_SCOPE_USER_INFO,URLEncoder.encode(returnUrl.replace("guiguketan", "#")));return "redirect:"+url;}@GetMapping("userInfo")public String getUserInfoUrl(@RequestParam("code") String code,@RequestParam("state") String returnUrl){try {//拿着code请求WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);//获取openidString openId = wxMpOAuth2AccessToken.getOpenId();log.info("openid:{}",openId);//获取微信信息WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);log.info("wxMpUser:{}", JSON.toJSONString(wxMpUser));//获取微信信息添加到数据库//先根据openid查询用户信息UserInfo userInfo=userInfoService.getUserInfoOpenid(openId);if(userInfo==null){ //数据库没有时添加到数据库中userInfo=new UserInfo();userInfo.setOpenId(openId);userInfo.setNickName(wxMpUser.getNickname());userInfo.setAvatar(wxMpUser.getHeadImgUrl());userInfo.setSex(wxMpUser.getSexId());userInfo.setProvince(wxMpUser.getProvince());userInfoService.save(userInfo);}//授权完成之后,跳转到具体的功能页面//生成token,按照一定规则生成字符串,可以包含用户信息String token= JwtHelper.createToken(userInfo.getId(),userInfo.getNickName());//localhost:8080/weixin?a=1&token=222if(returnUrl.indexOf("?")==-1){//若returnUrl中没有参数return "redirect:"+returnUrl+"?token="+token;}else{return "redirect:"+returnUrl+"&token="+token;}} catch (WxErrorException e) {e.printStackTrace();}return null;}
}
3.5 编写UserInfoService
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {//根据openid擦寻用户信息@Overridepublic UserInfo getUserInfoOpenid(String openId) {QueryWrapper<UserInfo> wrapper=new QueryWrapper<>();wrapper.eq("open_id",openId);UserInfo userInfo = baseMapper.selectOne(wrapper);return userInfo;}
}
3.6 使用token
通过token传递用户信息
我们在授权成功之后需要给前端返回一个token。
3.6.1 JWT介绍
我以前写过JWT,看这里:JWT实现跨域身份验证
JWT工具
JWT(Json Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上
JWT最重要的作用就是对 token信息的防伪作用。
3.6.2 JWT的原理
一个JWT由三个部分组成:公共部分、私有部分、签名部分。最后由这三者组合进行base64编码得到JWT。
(1)公共部分
主要是该JWT的相关配置参数,比如签名的加密算法、格式类型、过期时间等等。
(2)私有部分
用户自定义的内容,根据实际需要真正要封装的信息。
userInfo{用户的Id,用户的昵称nickName}
(3)签名部分
SaltiP: 当前服务器的Ip地址!{linux 中配置代理服务器的ip}
主要用户对JWT生成字符串的时候,进行加密{盐值}
base64编码,并不是加密,只是把明文信息变成了不可见的字符串。但是其实只要用一些工具就可以把base64编码解成明文,所以不要在JWT中放入涉及私密的信息。
3.6.3 整合JWT
(1)在service_utils模块添加依赖
<dependencies><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency>
</dependencies>
(2)添加JWT工具类
public class JwtHelper {//token字符串有效时间private static long tokenExpiration = 24*60*60*1000;//加密编码秘钥private static String tokenSignKey = "123456";//根据userid 和 username 生成token字符串public static String createToken(Long userId, String userName) {String token = Jwts.builder()//设置token分类.setSubject("GGKT-USER")//token字符串有效时长.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))//私有部分(用户信息).claim("userId", userId).claim("userName", userName)//根据秘钥使用加密编码方式进行加密,对字符串压缩.signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();return token;}//从token字符串获取useridpublic static Long getUserId(String token) {if(StringUtils.isEmpty(token)) return null;Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();Integer userId = (Integer)claims.get("userId");return userId.longValue();}//从token字符串获取getUserNamepublic static String getUserName(String token) {if(StringUtils.isEmpty(token)) return "";Jws<Claims> claimsJws= Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();return (String)claims.get("userName");}public static void main(String[] args) {String token = JwtHelper.createToken(1L, "lucy");System.out.println(token);System.out.println(JwtHelper.getUserId(token));System.out.println(JwtHelper.getUserName(token));}
}
测试下JWT的签发和验证:
eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAAKtWKi5NUrJScnf3DtENDXYNUtJRSq0oULIyNDMzNLM0MTc101EqLU4t8kwBikGYfom5qUAtOaXJlUq1AKdK54FBAAAA.6slWAzHg8oswGzWF411hOgX3i4yTAn-K7MwPBslbLhsXEw-ONikd06ydlDxboGEk8BpXnzm7VLKtrTToSH0w4A
1
lucy
3.7 微信授权登录测试
我们将负责授权的微服务以Debug模型运行。
进入微信公众号测试,随便点击个按钮
虽然泄露了我的域名,但是为了展示效果,我还是放出来吧,因为我看评论区好多人都在这一步卡住了。
继续放行,会出现用户授权,的用户同意授权,获取code
我在测试的时候已经同意过了。这里会自动登录。
然后拿着给的code,去换取网页授权access_token,然后再通过网页授权access_token和openid获取用户基本信息。到这一步授权已经成功。然后就是存数据库等操作了,页面跳转等就根据你自己业务做了。
可以看到,随着断点的不断放行,执行了
wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null)
方法后将我的微信名和openid、头像等等都查了出来,然后就可以存数据库等操作了,放行进入页面。我这里后面的页面还没做完,所以先暂时这样。
感觉这次的逻辑稍微有点乱,也可以去看我去年写过的另一篇微信扫码登录的文章:微信扫码登录实现
好了,到这里微信授权登录就做完了,有什么问题也可以找我交流,我看那个教学视频的评论区,大多数人都卡在这一步了。
微信授权登录功能实现相关推荐
- H5 微信授权登录功能实现
背景 最近几周面试复习以前知识库,刚好博客从国外迁移到国内CSND,同步坐下笔记,梳理之前开发H5 微信授权登录功能获取用户信息数据. H5页面微信授权登录,使用微信官方JSSDK,微信网页授权较为复 ...
- 【微信授权登录】uniapp开发小程序,实现获取微信授权登录功能
一.解题思路: 微信授权登录(获取用户信息) 1.先获取用户信息--用户授权允许后,通过调用uni.login 可以获取到code. 2.拿着获取到的code去调用--登录接口,可以获取到token. ...
- 微信授权登录功能(第三方网站登录)
写这篇博客的目的呢,一个是在于记录自己的开发过程,另一个目的就是将自己踩到的坑贴出来,供大家借鉴. 由于公司近期在做一个项目,在网页中使用微信扫码登录的功能,就开始了研究尝试,直到功能实现,从一脸懵逼 ...
- uni-app - 最详细 H5 网页接入微信登录功能,提供公众号配置与详细注释示例代码(移动端网页实现点击登录按钮后 调用微信公众号授权登录功能 详细讲解接入流程与详细示例代码)官方最新超级详细教程
前言 关于 uni-app 项目中接入微信授权登录的文章鱼龙混杂,各种乱代码.过时.没注释.不讲流程原理,非常难用. 本文实现了 uni-app H5 移动端网页项目,实现微信授权登录功能,详细讲解接 ...
- ios微信登录不上服务器,iOS微信授权登录
首先需要确保你的App应用在微信开发平台上注册创建并获得对应的接口,对应登录.支付等功能还涉及付费,具体申请流程就不再这里说了.到开放平台->管理中心->移动应用->查看应用,确认你 ...
- Android微信授权登录内存泄漏问题
最近有个APP中使用了微信授权登录功能,项目中我们采用leakcanary来检测内存泄漏,发现微信登录有内存泄漏的问题.现将解决过程记录如下,不确定与微信SDK版本有没关系,欢迎讨论指正. 一般我们是 ...
- uniapp - 超详细的 H5 公众号网页微信登录示例代码,提供从 0-1 公众号配置及详细注释代码(站在新手小白的角度)第三方微信授权登录的实现!!
介绍 目前示例是 "点击按钮登录",你也可以改为 "一进页面就登录" ,可随意改造. 百度的教程都太乱了,而且功能都有一定问题.本文主要讲解 uniapp H5 ...
- app登录时用QQ或者微信授权登录,及找回密码功能
前部分是QQ授权登录的,想看微信授权的直接跳下面 1.个人希望做到的饿效果效果如优酷的授权登录,但前提是你的应用必须在应用市场上架之后才可以做授权登录的操作 参照 :http://blog.csdn. ...
- uni-app授权登录功能的实现,包括微信授权、QQ授权
今天讲述一下购靓号平台APP的两种常用授权登录方式,废话不多说,公众号搜索[购靓号]自行体验.个人引以为豪的作品.哈哈哈 首先是APP微信授权登录 APP微信授权需要到微信开放平台申请,在hbuild ...
- 五行代码搞定微信授权登录
Authing 通过 SDK 为开发者提供了一种快速在微信网页中获取用户信息并完成登录的方法.如果用户在微信客户端中访问第三方网页.公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑 ...
最新文章
- 如何将知识图谱特征学习应用到推荐系统?
- 计算机二级vb重点知识,计算机二级《VB》历年考试重点知识
- linux vi修改后如何保存
- 页面布局与编写(续2)
- 面向数智营销的 AI FAAS 解决方案
- php封装的数据库操作文件夹,PHP中对数据库操作的封装_php
- SQL Server 2008内存性能监控
- *第十三周*数据结构实践项目一【验证Prim算法】
- Code::Blocks代码自动提示设置及常用快捷键 .
- GNS3各种IOS下载
- stvd watch 实时变量查看
- pandownload复活版下载 | 百度网盘下载速度慢的终极解决方案
- Elasticsearch——Keyword字段类型
- 隐藏APP图标并通过代码启动
- 单相Boost功率因数校正电路(PFC)设计与仿真(Simulink Saber):第二章 仿真模型搭建与控制参数整定
- 【数据可视化】Echarts世界地图需要的数据 - JSON格式世界国家中英文对照表
- uniapp下载文件 例(Word)以及下载其他文件,Word文件的转发,保存,查看
- 0x80070570文件或目录损坏且无法读取解决方法
- 【行业篇】一、汽车软硬架构 - EEA/SOA
- C语言学习(三)数据-浮点类型