项目整合微信扫码登录功能
项目整合微信登录功能
一、准备工作
https://open.weixin.qq.com
1、注册
2、邮箱激活
3、完善开发者资料
4、开发者资质认证
准备营业执照,1-2个工作日审批、300元
5、创建网站应用
提交审核,7个工作日审批
6、内网穿透
ngrok的使用
7、熟悉微信登录流程
参考文档:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=e547653f995d8f402704d5cb2945177dc8aa4e7e&lang=zh_CN
获取access_token时序图
二、后端开发
(1)生成授权URL
1、在项目用户模块的application.properties配置文件中添加相关配置信息
# 微信开放平台 appid
wx.open.app_id=你的appid# 微信开放平台 appsecret
wx.open.app_secret=你的appsecret# 微信开放平台 重定向url
wx.open.redirect_url=http://你的服务器名称/api/ucenter/wx/callback
2、在用户模块创建utils包并创建ConstantWeChatUtils常量类
@Component
public class ConstantWeChatUtils implements InitializingBean {@Value("${wx.open.app_id}")private String appid;@Value("${wx.open.app_secret}")private String appsecret;@Value("${wx.open.redirect_url}")private String redirectUrl;public static String WX_OPEN_APP_ID;public static String WX_OPEN_APP_SECRET;public static String WX_OPEN_REDIRECT_URL;@Overridepublic void afterPropertiesSet() throws Exception {WX_OPEN_APP_ID = appid;WX_OPEN_APP_SECRET = appsecret;WX_OPEN_REDIRECT_URL = redirectUrl;}
}
3、开通内网穿透隧道,指向本地微信扫码登录功能所在模块的端口号。
①登录ngrok官网:http://www.ngrok.cc
②注册账号,依据个人情况申请开通隧道。
③填写隧道相关配置
④申请成功后下载Ngrok客户端,并启动Ngrok
4、生成微信扫描二维码
①访问微信提供的固定的地址,向地址里面拼接参数,二维码就可以生成出来
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用唯一标识 |
redirect_uri | 是 | 请使用urlEncode对链接进行处理 |
response_type | 是 | 填code |
scope | 是 | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即 |
state | 是 | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 |
②创建生成二维码的方法(Controller)
@Controller
@RequestMapping("/api/ucenter/wx")
@Api(tags = "微信二维码生成接口")
@CrossOrigin
public class WxApiController {@ApiOperation(value = "生成微信扫码登录二维码")@GetMapping("login")public String genQrConnect() {//定义微信生成二维码固定地址//向地址里面拼接参数//%s 相当于是占位符String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +"?appid=%s" +"&redirect_uri=%s" +"&response_type=code" +"&scope=snsapi_login" +"&state=%s" +"#wechat_redirect";try {//redirecturl地址进行urlEncode编码String redirectUrl = ConstantWeChatUtils.WX_OPEN_REDIRECT_URL;redirectUrl = URLEncoder.encode(redirectUrl, "utf-8");//防止csrf攻击(跨站请求伪造攻击)//String state = UUID.randomUUID().toString().replaceAll("-", "");//一般情况下会使用一个随机数String state = "onlineeducation";//此处state设置的是我内网穿透中的前置域名//向%s位置传递参数值String formatUrl = String.format(baseUrl,ConstantWeChatUtils.WX_OPEN_APP_ID,redirectUrl,state);//重定向到拼接好的地址里面return "redirect:"+formatUrl;}catch(Exception e) {return null;}}
}
(2)开发回调URL
1.模块添加依赖
<!--httpclient-->
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.1</version>
</dependency>
<!--commons-io-->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>
<!--gson-->
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.2</version>
</dependency>
2.在utils包中创建httpclient工具类
工具类提取地址:https://pan.baidu.com/s/19h6935qHlZ-RSVEvjTlgOw
提取码:3wuo
3.在WxApiController中创建回调方法
@Autowired
private UcenterMemberService memberService;//此处注入的为项目中用户模块的service/**
* 1、获取回调参数
* 2、从redis中读取state进行比对,异常则拒绝调用
* 3、向微信的授权服务器发起请求,使用临时票据换取access_token
* 4、使用上一步获取的openid查询数据库,判断当前用户是否已注册,如果已注册则直接进行登录操作
* 5、如果未注册,则使用openid和access_token向微信的资源服务器发起请求,请求获取微信的用户信息
* 5.1、将获取到的用户信息存入数据库
* 5.2、然后进行登录操作
*
* @param code
* @param state
* @return
*/
@GetMapping("callback")
@ApiOperation(value = "扫描成功后的回调方法")
public String callback(String code,String state) {//code参数:临时票据,随机字符串,类似于手机验证码//state参数:生成二维码传递state值//1 获取code临时票据//2 请求微信固定地址,得到acess_token和openidString baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +"?appid=%s" +"&secret=%s" +"&code=%s" +"&grant_type=authorization_code";//拼接参数baseAccessTokenUrl = String.format(baseAccessTokenUrl,ConstantWeChatUtils.WX_OPEN_APP_ID,ConstantWeChatUtils.WX_OPEN_APP_SECRET,code);try {//请求这个带参数地址,得到acess_token和openid//使用httpclientString accessTokenResult = HttpClientUtils.get(baseAccessTokenUrl);// System.out.println("*********************accessTokenResult: "+accessTokenResult);//得到acess_token和openidGson gson = new Gson();//把accessTokenResult字符串转换map类型HashMap accessTokenMap = gson.fromJson(accessTokenResult, HashMap.class);String access_token = (String)accessTokenMap.get("access_token");String openid = (String)accessTokenMap.get("openid");//3 拿着acess_token和openid再去请求微信固定地址,得到扫描人信息String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +"?access_token=%s" +"&openid=%s";baseUserInfoUrl = String.format(baseUserInfoUrl,access_token,openid);//请求地址String userInfoResult = HttpClientUtils.get(baseUserInfoUrl);HashMap userInfoMap = gson.fromJson(userInfoResult, HashMap.class);String nickname = (String)userInfoMap.get("nickname");String headimgurl = (String)userInfoMap.get("headimgurl");//4 把获取微信扫描人信息添加数据库里面//添加信息之前判断,根据openid进行判断,如果表存储相同用户信息不需要添加//需要给用户设置哪些信息根据自己的表字段进行设置UcenterMember member = memberService.getUserInfoByOpenId(openid);if(member == null) {//表不存在相同用户,进行添加member = new UcenterMember();member.setOpenid(openid);member.setNickname(nickname);member.setAvatar(headimgurl);memberService.save(member);}}catch(Exception e) {}return null;
}
其中accessTokenResult中得到的数据为:
userInfoResult中得到的数据为:
4.完善业务层
添加信息之前通过openid判断用户信息是否存在的代码
//根据openid查询扫码登录的用户是否存在
@Override
public UcenterMember getUserInfoByOpenId(String openid) {QueryWrapper<UcenterMember> wrapper = new QueryWrapper<>();wrapper.eq("openid",openid);UcenterMember member = baseMapper.selectOne(wrapper);return member;
}
(3)整合JWT令牌
1.加入jwt工具依赖
<!-- JWT -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.7.0</version>
</dependency>
2.在utils包中创建JWT工具类
public class JwtUtils {public static final String SUBJECT = "guli";//名字随意//秘钥public static final String APPSECRET = "guli";//名字随意public static final long EXPIRE = 1000 * 60 * 30; //过期时间,毫秒,30分钟/*** 根据对象生成jwt的字符串** @param member* @return*/public static String geneJsonWebToken(UcenterMember member) {if (member == null || StringUtils.isEmpty(member.getId())|| StringUtils.isEmpty(member.getNickname())|| StringUtils.isEmpty(member.getAvatar())) {return null;}String token = Jwts.builder().setSubject(SUBJECT).claim("id", member.getId()).claim("nickname", member.getNickname()).claim("avatar", member.getAvatar()).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRE)).signWith(SignatureAlgorithm.HS256, APPSECRET).compact();return token;}/*** 根据jwt的token字符串,从字符串获取用户信息** @param token* @return*/public static Claims checkJWT(String token) {//claims类似于map集合Claims claims = Jwts.parser().setSigningKey(APPSECRET).parseClaimsJws(token).getBody();return claims;}}
3.callback中生成jwt
在WxApiController.java的callback方法的最后添加如下代码
// 生成jwt
String token = JwtUtils.geneJsonWebToken(member);//存入cookie
//CookieUtils.setCookie(request, response, "guli_jwt_token", token);//因为端口号不同存在蛞蝓问题,cookie不能跨域,所以这里使用url重写
return "redirect:http://localhost:3000?token=" + token;
4、前端打印token(前端采用的是NUXT服务器端渲染技术)
在layout/defaullt.vue中打印获取的token值
export default {created() {console.log(this.$route.query.token)}
}
5.前端首页面获取路由token值,调用接口,根据token得到token里面用户信息,返回进行显示
(1)编写接口,根据token字符串获取用户信息
@PostMapping("getUserInfoToken/{token}")
@ApiOperation(value = "根据token获取token里面的用户信息")
public R getUserInfoToken(@PathVariable String token) {Claims claims = JwtUtils.checkJWT(token);String id = (String)claims.get("id");String nickname = (String)claims.get("nickname");String avatar = (String)claims.get("avatar");UcenterMember member = new UcenterMember();member.setId(id);member.setNickname(nickname);member.setAvatar(avatar);return R.ok().data("member",member);
}
三、前端整合(NUXT)
创建页面
1、注册页
pages/register.vue
<template><div class="main"><div class="title"><a href="/login">登录</a><span>·</span><a class="active" href="/register">注册</a></div>
<div class="sign-up-container"><form action="register"><div class="input-prepend restyle"><input type="text" placeholder="你的昵称"><i class="iconfont icon-user"/></div><div class="input-prepend restyle no-radius"><input type="text" placeholder="手机号"><i class="iconfont icon-phone"/></div><div class="input-prepend"><input type="password" placeholder="设置密码"><i class="iconfont icon-password"/></div><div class="btn"><input type="submit" class="sign-up-button" value="注册"></div><p class="sign-up-msg">点击 “注册” 即表示您同意并愿意遵守简书<br><a target="_blank" href="http://www.jianshu.com/p/c44d171298ce">用户协议</a>和<a target="_blank" href="http://www.jianshu.com/p/2ov8x3">隐私政策</a> 。</p></form><!-- 更多注册方式 --><div class="more-sign"><h6>社交帐号直接注册</h6><ul><li><a id="weixin" class="weixin" target="_blank" href="http://localhost:8004/api/ucenter/wx/login"><i class="iconfont icon-weixin"/></a></li><li><a id="qq" class="qq" target="_blank" href="#"><i class="iconfont icon-qq"/></a></li></ul></div></div></div>
</template>
<script>
import '~/assets/css/sign.css'
import '~/assets/css/iconfont.css'
export default {layout: 'sign'
}
</script>
在整合前端添加微信扫码登录时,注意将href请求路径填写为自己后台的路径即可。
2、登录页面
pages/login.vue
<template><div class="main"><div class="title"><a class="active" href="/login">登录</a><span>·</span><a href="/register">注册</a></div>
<div class="sign-up-container"><form action="register"><div class="input-prepend restyle"><input type="text" placeholder="手机号"><i class="iconfont icon-phone"/></div><div class="input-prepend"><input type="password" placeholder="密码"><i class="iconfont icon-password"/></div><div class="btn"><input type="submit" class="sign-in-button" value="登录"></div></form><!-- 更多登录方式 --><div class="more-sign"><h6>社交帐号登录</h6><ul><li><a id="weixin" class="weixin" target="_blank" href="http://localhost:8004/api/ucenter/wx/login"><i class="iconfont icon-weixin"/></a></li><li><a id="qq" class="qq" target="_blank" href="#"><i class="iconfont icon-qq"/></a></li></ul></div></div>
</div>
</template>
<script>
import '~/assets/css/sign.css'
import '~/assets/css/iconfont.css'
export default {layout: 'sign'
}
</script>
项目整合微信扫码登录功能相关推荐
- Vue - 实现微信扫码登录功能(项目植入微信扫码登录功能)超详细完整流程详解及详细代码及注释,附带完整功能源码、常见问题解决方案
前言 如果您需要 Nuxt.js 版本的教程,请访问 Nuxt.js - 微信扫码登录功能. 网上的大部分教程都太乱且没有任何注释和解释,对于新手而言简直是根本无从下手, 本文将站在新手小白的角度,从 ...
- Nuxt - 实现微信扫码登录功能(SSR 服务端渲染项目植入微信扫码登录功能)超详细完整流程详解及详细代码及注释,附带完整功能源码、常见问题解决方案
前言 如果您需要 Vue.js 版本的教程,请访问 Vue.js - 微信扫码登录功能. 网上的大部分教程都太乱且没有任何注释和解释,对于新手而言简直是根本无从下手, 本文将站在新手小白的角度,从 0 ...
- SpringBoot整合微信扫码登录
SpringBoot整合微信扫码登录 准备工作 基本思路流程 搭建SpringBoot 引入依赖 加入配置文件 代码实现 工具类 controller层 结果 准备工作 1.登录官网了解到,学习者想本 ...
- 微信扫码登录功能实现
原因:很简单,公司的账号登录需要用到微信扫码登录与QQ的登录功能,所以,在做好了微信的扫码登录之后,本人就写这篇微信扫码登录功能实现的教程 教程开始 需要用到的网站: https://open.wei ...
- vue实现网页端企业微信扫码登录功能(前端部分)
时至今日,企业微信在企业日常工作中的使用越来越频繁也越来越重要,不少企业已使用企业微信进行着日常的工作安排管理.在这种背景下,各类系统和企业微信对接的需求也不断增加,今天要说的就是一个比较常见的需求 ...
- Java后台实现网站微信扫码登录功能,获取用户openid,及微信用户信息(小程序码方案),关联微信小程序(个人主体小程序也可以)
目录 前言 操作流程 1.注册微信小程序 2.通过后台获取小程序码 注意事项 时序图理解 方案实现步骤 前言 很多业务场景之下我们需要实现微信扫码登录检测登录状态的需求,或需要同步网站与小程序的用户信 ...
- web网站整合微信扫码登录
1.准备工作 https://open.weixin.qq.com 1.注册 2.邮箱激活 3.完善开发者资料 4.开发者资质认证 准备营业执照,1-2个工作日审批.300元 5.创建网站应用 提交审 ...
- 项目实战-微信扫码登录
调用微信的接口报错errcode: 40164 调用微信的接口报错 { errcode: 40164, errmsg: 'invalid ip 117.100.47.169 ipv6 ::ffff:1 ...
- 微信扫码登录功能报错 errcode 41001.0 errmsg access_token missing rid
报错原因:安全中心未配置IP白名单,导致access_token无效,添加后就可以 全局返回码说明
最新文章
- 驰骋工作流引擎设计系列04 流程引擎表结构的设计
- 基于SSM实现新闻推荐系统
- Servlet学习DAY_02:重定向/ 文件上传/ Cookie和Session/ 导入一个工程 / 配置欢迎页面 / 同步请求和异步请求/JSON和AJax介绍 /过滤器
- 大数据之Linux早课9.21
- XCTF(攻防世界)—进阶web题Write Up(一)
- ITK:过滤器Filter和ParallelizeImageRegion比较
- 0x84bb0001 sqlserver_sqlserver 2000 远程连接 服务器的解决方案
- LeetCode Algorithm 160. 相交链表
- Html爱情表白动画
- SPOJ Problem 6219:Edit distance
- windows10下Kafka环境搭建
- 为Go编译的Windows程序加入资源文件
- 小团队适合引入 Spring Cloud 微服务吗?
- 一个空格惹的祸:服务器端接收不到前端采用问号传参方式传过来的值
- PHP api接口开发
- 让 Code Review成为一种习惯
- PLC控制系统设计与调试的一般步骤
- WindowsCMD配置代理
- 2023 年(MCM/ICM)美国大学生数学建模竞赛参赛规则及注意事项
- Vue开发警告[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
热门文章
- [产品分析] Palm Pre,iPhone,Gphone全面大比拼
- 微软将开启PC Win10 20H2正式版强制升级
- GDAL综合整理--7:GDAL实用工具简介
- 尚硅谷李立超老师讲解web前端---笔记(持续更新)
- 荣耀手表gs3和华为gt3 哪个好
- Web课程设计-仿当当网-增删改查-java+jsp+mysql-期末大作业
- SRAM、PSRAM、SPI FLASH
- 大学英语(第三册)复习(原文及全文翻译)——Unit 1 - A Brush with the Law(与警察的一场小冲突)
- Endsley 的情境意识理论回顾
- ue4 小知识点 图片变灰 hlsl 材质 custom shader