博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
项目整合微信扫码登录功能
阅读量:3889 次
发布时间:2019-05-23

本文共 9617 字,大约阅读时间需要 32 分钟。

项目整合微信登录功能

一、准备工作

1、注册

2、邮箱激活

3、完善开发者资料

4、开发者资质认证

准备营业执照,1-2个工作日审批、300元

5、创建网站应用

提交审核,7个工作日审批

6、内网穿透

ngrok的使用

7、熟悉微信登录流程

参考文档:

获取access_token时序图

在这里插入图片描述

二、后端开发

(1)生成授权URL

1、在项目用户模块的application.properties配置文件中添加相关配置信息

# 微信开放平台 appidwx.open.app_id=你的appid# 微信开放平台 appsecretwx.open.app_secret=你的appsecret# 微信开放平台 重定向urlwx.open.redirect_url=http://你的服务器名称/api/ucenter/wx/callback

2、在用户模块创建utils包并创建ConstantWeChatUtils常量类

@Componentpublic 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; @Override public 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 = "微信二维码生成接口")@CrossOriginpublic 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.模块添加依赖

org.apache.httpcomponents
httpclient
4.5.1
commons-io
commons-io
2.6
com.google.code.gson
gson
2.8.2

2.在utils包中创建httpclient工具类

工具类提取地址:

提取码:3wuo

3.在WxApiController中创建回调方法

@Autowiredprivate 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和openid String 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 //使用httpclient String accessTokenResult = HttpClientUtils.get(baseAccessTokenUrl); // System.out.println("*********************accessTokenResult: "+accessTokenResult); //得到acess_token和openid Gson 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查询扫码登录的用户是否存在@Overridepublic UcenterMember getUserInfoByOpenId(String openid) {
QueryWrapper
wrapper = new QueryWrapper<>(); wrapper.eq("openid",openid); UcenterMember member = baseMapper.selectOne(wrapper); return member;}

(3)整合JWT令牌

1.加入jwt工具依赖

io.jsonwebtoken
jjwt
0.7.0

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方法的最后添加如下代码

// 生成jwtString 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

在整合前端添加微信扫码登录时,注意将href请求路径填写为自己后台的路径即可。

在这里插入图片描述

2、登录页面

pages/login.vue

在这里插入图片描述

转载地址:http://mpshn.baihongyu.com/

你可能感兴趣的文章
结构体最后定义一个char p[0];这样的成员有何意义(转)
查看>>
一步一学Linux与Windows 共享文件Samba (v0.2b)
查看>>
Linux 下忘记root密码怎么办
查看>>
Linux软件下载源码编程文章资料周立发--之调试
查看>>
GIT分支管理是一门艺术
查看>>
Cscope在emacs中的配置与使用
查看>>
emacs 2.4安装问题 ecb
查看>>
ecb里使用自定义快捷键切换窗口
查看>>
vim(gvim)支持对齐线
查看>>
CentOS编译安装Lighttpd1.4.28
查看>>
实践HTTP206状态:部分内容和范围请求
查看>>
【C++基础】拷贝构造函数的参数必须是引用类型
查看>>
【C++基础】virtual析构函数
查看>>
【Java基础】面向对象
查看>>
【Java.Web】web.xml详解
查看>>
J2EE的技术体系
查看>>
【Java.Web】Java Web应用程序的规范目录结构,*WEB组件的URL/入口*
查看>>
【基础篇】计算机网络
查看>>
OSI 7层详解
查看>>
【C++基础】重载overload、重写(覆盖)override、隐藏hide的区别
查看>>