项目整合微信登录功能

一、准备工作

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>

项目整合微信扫码登录功能相关推荐

  1. Vue - 实现微信扫码登录功能(项目植入微信扫码登录功能)超详细完整流程详解及详细代码及注释,附带完整功能源码、常见问题解决方案

    前言 如果您需要 Nuxt.js 版本的教程,请访问 Nuxt.js - 微信扫码登录功能. 网上的大部分教程都太乱且没有任何注释和解释,对于新手而言简直是根本无从下手, 本文将站在新手小白的角度,从 ...

  2. Nuxt - 实现微信扫码登录功能(SSR 服务端渲染项目植入微信扫码登录功能)超详细完整流程详解及详细代码及注释,附带完整功能源码、常见问题解决方案

    前言 如果您需要 Vue.js 版本的教程,请访问 Vue.js - 微信扫码登录功能. 网上的大部分教程都太乱且没有任何注释和解释,对于新手而言简直是根本无从下手, 本文将站在新手小白的角度,从 0 ...

  3. SpringBoot整合微信扫码登录

    SpringBoot整合微信扫码登录 准备工作 基本思路流程 搭建SpringBoot 引入依赖 加入配置文件 代码实现 工具类 controller层 结果 准备工作 1.登录官网了解到,学习者想本 ...

  4. 微信扫码登录功能实现

    原因:很简单,公司的账号登录需要用到微信扫码登录与QQ的登录功能,所以,在做好了微信的扫码登录之后,本人就写这篇微信扫码登录功能实现的教程 教程开始 需要用到的网站: https://open.wei ...

  5. vue实现网页端企业微信扫码登录功能(前端部分)

     时至今日,企业微信在企业日常工作中的使用越来越频繁也越来越重要,不少企业已使用企业微信进行着日常的工作安排管理.在这种背景下,各类系统和企业微信对接的需求也不断增加,今天要说的就是一个比较常见的需求 ...

  6. Java后台实现网站微信扫码登录功能,获取用户openid,及微信用户信息(小程序码方案),关联微信小程序(个人主体小程序也可以)

    目录 前言 操作流程 1.注册微信小程序 2.通过后台获取小程序码 注意事项 时序图理解 方案实现步骤 前言 很多业务场景之下我们需要实现微信扫码登录检测登录状态的需求,或需要同步网站与小程序的用户信 ...

  7. web网站整合微信扫码登录

    1.准备工作 https://open.weixin.qq.com 1.注册 2.邮箱激活 3.完善开发者资料 4.开发者资质认证 准备营业执照,1-2个工作日审批.300元 5.创建网站应用 提交审 ...

  8. 项目实战-微信扫码登录

    调用微信的接口报错errcode: 40164 调用微信的接口报错 { errcode: 40164, errmsg: 'invalid ip 117.100.47.169 ipv6 ::ffff:1 ...

  9. 微信扫码登录功能报错 errcode 41001.0 errmsg access_token missing rid

    报错原因:安全中心未配置IP白名单,导致access_token无效,添加后就可以 全局返回码说明

最新文章

  1. 驰骋工作流引擎设计系列04 流程引擎表结构的设计
  2. 基于SSM实现新闻推荐系统
  3. Servlet学习DAY_02:重定向/ 文件上传/ Cookie和Session/ 导入一个工程 / 配置欢迎页面 / 同步请求和异步请求/JSON和AJax介绍 /过滤器
  4. 大数据之Linux早课9.21
  5. XCTF(攻防世界)—进阶web题Write Up(一)
  6. ITK:过滤器Filter和ParallelizeImageRegion比较
  7. 0x84bb0001 sqlserver_sqlserver 2000 远程连接 服务器的解决方案
  8. LeetCode Algorithm 160. 相交链表
  9. Html爱情表白动画
  10. SPOJ Problem 6219:Edit distance
  11. windows10下Kafka环境搭建
  12. 为Go编译的Windows程序加入资源文件
  13. 小团队适合引入 Spring Cloud 微服务吗?
  14. 一个空格惹的祸:服务器端接收不到前端采用问号传参方式传过来的值
  15. PHP api接口开发
  16. 让 Code Review成为一种习惯
  17. PLC控制系统设计与调试的一般步骤
  18. WindowsCMD配置代理
  19. 2023 年(MCM/ICM)美国大学生数学建模竞赛参赛规则及注意事项
  20. Vue开发警告[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.

热门文章

  1. [产品分析] Palm Pre,iPhone,Gphone全面大比拼
  2. 微软将开启PC Win10 20H2正式版强制升级
  3. GDAL综合整理--7:GDAL实用工具简介
  4. 尚硅谷李立超老师讲解web前端---笔记(持续更新)
  5. 荣耀手表gs3和华为gt3 哪个好
  6. Web课程设计-仿当当网-增删改查-java+jsp+mysql-期末大作业
  7. SRAM、PSRAM、SPI FLASH
  8. 大学英语(第三册)复习(原文及全文翻译)——Unit 1 - A Brush with the Law(与警察的一场小冲突)
  9. Endsley 的情境意识理论回顾
  10. ue4 小知识点 图片变灰 hlsl 材质 custom shader