第三方登录

用户不想去注册你的网站,觉得输入这些信息麻烦。更愿意像直接扫码进行登录这样,简单。

扫码人的信息自动注册,加入到你的数据库中。

微信登录是一个固定的流程,是腾讯规定的固定流程去做。

微信登录讲解之前,先讲解OAuth2

OAuth2是什么?

OAuth2是针对特定问题的一种解决方案。

主要可以解决两个问题:

1. 开放系统间授权   2.分布式访问问题

开放系统间授权:

lucy照了很多照片,她把它们都存到了自己的百度网盘上去了。但是百度网盘没法打印照片啊,某公司自己研发了一款系统,专门用于这种云存储的打印服务。

但是,默认情况下,这款系统默认是不能操作lucy存到她百度网盘上的东西的。没有权限。

但是百度网盘提供了授权服务的相关方法。

这个时候,只要lucy授权给这款打印系统,那么就可以实现打印服务。

具体怎么做到的,这就是OAuth2要做的事情。也是百度网盘要规定的流程。

分布式访问

我们只需要把token相关的代码抽取出来,生成一个公共的类。

这样,即使是不同的模块之间,他们的token创建和解析的加密方式也都是一样的,也就能解析到cookie中传过来的token信息,进行登录。

当然了,我们可以使用redis存储token以及对应用户信息,这样不同模块就都能拿到用户信息。否则的话,我们只知道是当前用户,当前用户的用户信息,也只是token解析出来的信息。比如用户id。当然,因为用户id具有唯一性嘛,所以通过用户id关联自己模块的业务也是可以的。比如:某人登录了视频服务,在视频服务会存储一个视频记录的数据表。这个时候,只要数据表关联用户id就可以了。对于视频服务而言,是没有问题的。

OAuth2解决方案:按照一定规则生成字符串,字符串包含用户信息。

OAuth2只是一种解决方案,这种方案具体怎么做由方案提供者自己定。

下面我们开始进行微信扫码登录:

准备工作

1. 首先你想要使用腾讯公司微信做登录这样的相关操作,必须在腾讯的开发者平台注册,获得资质!微信开放平台

(1) 支持企业类型(以前只支持企业注册)

(2) 注册之后,会给你提供微信id和微信密钥

ps:注册需要准备营业执照、1-2个工作日审批、300元认证费

2. 申请网站应用名称。

就是说你扫描二维码,它会显示当前网站的应用名称,比如:我的谷粒。这个一般在7个工作日内审批。

3. 需要域名地址。

地址作用:微信扫完二维码之后,找你的域名做跳转。

熟悉微信登录流程:

下面我们快速看一下

参考文档:微信开放平台

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

后端开发(重点)

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、创建常量类

创建util包,创建ConstantWxUtils.java常量类

package com.atguigu.educenter.utils;import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component
public class ConstantWxUtils 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、生成微信扫描的二维码

直接请求微信提供的固定的地址,向地址的后面拼接参数即可。

即重定向到微信的二维码生成地址去。

https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirects

参数说明:

参数 是否必须 说明
appid 应用唯一标识
redirect_uri 请使用urlEncode对链接进行处理
response_type 填code
scope 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即
state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

在当前educenter模块中创建api包

api包中创建WxApiController

代码的写法

package com.atguigu.educenter.controller;import com.atguigu.educenter.utils.ConstantWxUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;import java.net.URLEncoder;@CrossOrigin
@Controller  //只是请求地址,不需要返回数据,这个时候不能用@RestController
@RequestMapping("/api/ucenter/wx")
public class WxApiController {//1 生成微信扫描二维码@GetMapping("login")public String getWxCode() {//固定地址,后面拼接参数//写法一(这么做效率很低,多了还容易写错):
//        String url = "https://open.weixin.qq.com/connect/qrconnect" +
//                "?appid="+
//                ConstantWxUtils.WX_OPEN_APP_ID +
//                "&redirect_uri=" +
//                ConstantWxUtils.WX_OPEN_REDIRECT_URL +
//                "&response_type=code" +
//                "&scope=snsapi_login" +
//                "state=atguigu" +
//                "#wechat_redirect";//当然,上面这个redirect_uri地址要先编码再进行传,不能那样直接传。//写法二(推荐)// 微信开放平台授权baseUrl  %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";//对redirect_url进行URLEncoder编码String redirectUrl = ConstantWxUtils.WX_OPEN_REDIRECT_URL;try {redirectUrl = URLEncoder.encode(redirectUrl, "utf-8");}catch(Exception e) {}//设置%s里面值String url = String.format(baseUrl,ConstantWxUtils.WX_OPEN_APP_ID,redirectUrl,"atguigu");//重定向到请求微信地址里面return "redirect:" + url;}
}

此时启动改服务,然后请求当前接口:localhost:8160/api/ucenter/wx/login

它会根据你接口中写的代码,重定向到微信的二维码生成地址,拼接的参数就是你传的参数

比如:

https://open.weixin.qq.com/connect/qrconnect?appid=wxed9954c01bb80b37&redirect_uri=http%3A%2F%2Flocalhost%3A8160%2Fapi%2Fucenter%2Fwx%2Fcallback&response_type=code&scope=snsapi_login&state=atguigu#wechat_redirect

4.扫描后获取用户信息的过程

扫描成功确认之后,微信会获取到用户的一个code值。然后微信会把code值给到我们,跳转到如下我们的回调地址,地址后拼接了code参数和state参数:

localhost:8160/api/ucenter/wx/callback?code=021Grg0w34r37Z2c9S2w3xmv180Grg0o&state=atguigu

api/ucenter/wx/callback肯定不是我们的地址,我们还没有写这个方法。

ps:这个回调地址就是我们之前在配置文件中配置的redirect_url重定向地址,它是当初注册资质时填写的域名地址。在获取验证码时就传递给了微信,这个时候微信在将地址返回给我们。

wx.open.redirect_url=http://localhost:8160/api/ucenter/wx/callback

这个回调方法的作用就是用于我们获取用户信息。微信说让我们用这个接口去请求用户信息。

下面我们就需要自己来写这个回调方法,在方法里面,通过获取到微信传回来的code值,带着这个值去请求微信另外的一个固定地址获取asses_token,openid

通过httpclint直接请求微信,然后获取到返回的accsess_token 和 openid信息。

接着我们可以把它当前用户信息加入到自己的数据库。(你也可以选择不加入)

首先判断当前用户的openid是否在自己的数据库已经存在,如果存在不用添加了。

如果不存在,那么就通过这个accsess_token 和 openid再去请求微信的又一个固定地址,获取用户信息。

还是通过HttpClient发送请求,然后接收返回值。

一样也需要通过json转换工具转换成字符串。否则是json格式的数据无法操作。

拿到用户信息后我们就可以加入到自己的数据库里面了。

我们看看代码怎么写:

package com.atguigu.educenter.controller;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.atguigu.commonutils.JwtUtils;
import com.atguigu.educenter.bean.UcenterMember;
import com.atguigu.educenter.service.UcenterMemberService;
import com.atguigu.educenter.utils.ConstantWxUtils;
import com.atguigu.educenter.utils.HttpClientUtils;
import com.atguigu.servicebase.exceptionHandler.GuliException;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;@CrossOrigin
@Controller  //只是请求地址,不需要返回数据。这个时候不能用@RestController
@RequestMapping("/api/ucenter/wx")
public class WxApiController {@Autowiredprivate UcenterMemberService memberService;//2 获取扫描人信息,添加数据@GetMapping("callback")public String callback(String code, String state) {try {//1 获取code值,临时票据,类似于验证码//2 拿着code请求 微信固定的地址,得到两个值 accsess_token 和 openidString baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +"?appid=%s" +"&secret=%s" +"&code=%s" +"&grant_type=authorization_code";//拼接三个参数 :id  秘钥 和 code值String accessTokenUrl = String.format(baseAccessTokenUrl,ConstantWxUtils.WX_OPEN_APP_ID,ConstantWxUtils.WX_OPEN_APP_SECRET,code);//请求这个拼接好的地址,得到返回两个值 accsess_token 和 openid//使用httpclient发送请求,得到返回结果String accessTokenInfo = HttpClientUtils.get(accessTokenUrl);//从accessTokenInfo字符串获取出来两个值 accsess_token 和 openid//把accessTokenInfo字符串转换map集合,根据map里面key获取对应值//使用json转换工具 GsonGson gson = new Gson();HashMap mapAccessToken = gson.fromJson(accessTokenInfo, HashMap.class);String access_token = (String)mapAccessToken.get("access_token");String openid = (String)mapAccessToken.get("openid");//把扫描人信息添加数据库里面//判断数据表里面是否存在相同微信信息,根据openid判断UcenterMember member = memberService.getOpenIdMember(openid);if(member == null) {//memeber是空,表没有相同微信数据,进行添加//3 拿着得到accsess_token 和 openid,再去请求微信提供固定的地址,获取到扫描人信息//访问微信的资源服务器,获取用户信息String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +"?access_token=%s" +"&openid=%s";//拼接两个参数String userInfoUrl = String.format(baseUserInfoUrl,access_token,openid);//发送请求String userInfo = HttpClientUtils.get(userInfoUrl);//获取返回userinfo字符串扫描人信息HashMap userInfoMap = gson.fromJson(userInfo, HashMap.class);String nickname = (String)userInfoMap.get("nickname");//昵称String headimgurl = (String)userInfoMap.get("headimgurl");//头像member = new UcenterMember();member.setOpenid(openid);member.setNickname(nickname);member.setAvatar(headimgurl);memberService.save(member);}//使用jwt根据member对象生成token字符串String jwtToken = JwtUtils.getJwtToken(member.getId(), member.getNickname());//最后:返回首页面,通过路径传递token字符串return "redirect:http://localhost:3000?token="+jwtToken;}catch(Exception e) {throw new GuliException(20001,"登录失败");}}//1 生成微信扫描二维码@GetMapping("login")public String getWxCode() {//固定地址,后面拼接参数//写法一(这么做效率很低,多了还容易写错):
//        String url = "https://open.weixin.qq.com/connect/qrconnect" +
//                "?appid="+
//                ConstantWxUtils.WX_OPEN_APP_ID +
//                "&redirect_uri=" +
//                ConstantWxUtils.WX_OPEN_REDIRECT_URL +
//                "&response_type=code" +
//                "&scope=snsapi_login" +
//                "state=atguigu" +
//                "#wechat_redirect";//当然,上面这个redirect_uri地址要先编码再进行传,不能那样直接传。//写法二(推荐)// 微信开放平台授权baseUrl  %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";//对redirect_url进行URLEncoder编码String redirectUrl = ConstantWxUtils.WX_OPEN_REDIRECT_URL;try {redirectUrl = URLEncoder.encode(redirectUrl, "utf-8");}catch(Exception e) {}//设置%s里面值String url = String.format(baseUrl,ConstantWxUtils.WX_OPEN_APP_ID,redirectUrl,"atguigu");//重定向到请求微信地址里面return "redirect:" + url;}
}

当然json转换工具你自己选择,fastjson也可以。比如:

    //对比Gson和FastJson    //GsonGson gson = new Gson();HashMap mapAccessToken = gson.fromJson(accessTokenInfo, HashMap.class);String access_token = (String)mapAccessToken.get("access_token");String openid = (String)mapAccessToken.get("openid");//FastJsonMap parse = (Map) JSON.parse(accessTokenInfo);String access_token1 = (String) parse.get("access_token");System.out.println(access_token1 +"这是fastjson解析出来的");

我们这里怎么写都对,因为都是localhost,但是实际项目中,我们不建议这么做。

然后在首页页面中显示用户信息

如何实现微信扫码登录--OAuth2相关推荐

  1. 微信开放平台开发——网页微信扫码登录(OAuth2.0)

    1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...

  2. 微信官方你真的懂OAuth2?Spring Security OAuth2整合企业微信扫码登录

    ❝ 企业微信扫码登录DEMO参见文末. 现在很多企业都接入了企业微信,作为私域社群工具,企业微信开放了很多API,可以打通很多自有的应用.既然是应用,那肯定需要做登录.正好企业微信提供了企业微信扫码授 ...

  3. 通过微信扫码登录剖析 oauth2 认证授权技术

    本文目录 前言 趣味解读oauth2 oauth2精髓 oauth2核心概念 结合微信登录深刻理解oauht2 本文小结 前言 相信很多小伙伴在学习 JAVA 的过程中或多或少接触或者开发过类似于 x ...

  4. Spring Boot + OAuth2.0 实现微信扫码登录,这才叫优雅

    点击"终码一生",关注,置顶公众号 每日技术干货,第一时间送达! 微信开放平台:微信扫码登录功能 官方文档:https://developers.weixin.qq.com/doc ...

  5. Spring Boot + OAuth2.0 实现微信扫码登录,这才叫优雅!!

    微信开放平台:微信扫码登录功能 官方文档:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_ ...

  6. SpringSecurity OAuth2实现单点登录,微信扫码登录,Redis缓存验证码---入门到实战

    1. 认证授权 1.1 什么是认证授权 ​ 例如课程发布后用户通过在线学习页面点播视频进行学习.如何去记录学生的学习过程呢?要想掌握学生的学习情况就需要知道用户的身份信息,记录哪个用户在什么时间学习什 ...

  7. Vue+abp微信扫码登录

    最近系统中要使用微信扫码登录,根据微信官方文档和网络搜索相关文献实现了.分享给需要的人,也作为自己的一个笔记.后端系统是基于ABP的,所以部分代码直接使用了abp的接口,直接拷贝代码编译不通过. 注册 ...

  8. SpringBoot整合微信扫码登录

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

  9. 项目整合微信扫码登录功能

    项目整合微信登录功能 一.准备工作 https://open.weixin.qq.com 1.注册 2.邮箱激活 3.完善开发者资料 4.开发者资质认证 准备营业执照,1-2个工作日审批.300元 5 ...

  10. Spring学习笔记(二十三)——实现网站微信扫码登录获取微信用户信息Demo

    目录 微信扫码登录介绍 开发步骤 微信扫码登录示例 微信开放文档 遇到的问题 使用第三方工具实现网站微信扫码登录 开发前介绍 开发步骤 微信扫码登录获取微信用户信息Demo实现流程 实现效果 实现过程 ...

最新文章

  1. P2642 双子序列最大和(线性DP)(最大子段和 + 合唱队列)
  2. R语言生成螺旋形(spirals)仿真数据实战:螺旋线型线性不可分数据集、螺旋线型不可分数据集可视化、为散点图中的每个数据点添加类标签信息
  3. java如何画周期sanjiao信号_如何声明一个可变长度的std_logic_vector信号
  4. 单语言表征如何迁移到多语言去?
  5. 微软发布通用型AI框架Avatar Framework
  6. 辅助改方办理方法 计算机联锁,辅助所
  7. MFC:怎么将程序窗口最小化到系统托盘
  8. 计算机类专计算机网络基础与应用,2016年秋季学期计算机专业《计算机网络基础(专)》第一次语音答疑.ppt...
  9. bgi::detail::intersection_content用法的测试程序
  10. 推荐7个高质量的学术公众号
  11. RTSP协议基本分析
  12. MySQL子查询作为列_mysql 列子查询
  13. error:bucket is protected
  14. 修改Linux默认启动级别或模式的方法
  15. 如何彻底关闭FF新推荐弹出广告
  16. Udacity 传感器融合笔记 (一)lidar
  17. Python实现excel表格合并
  18. 自制智能手机电话APP
  19. 多米诺骨牌上演:三箭资本崩盘始末
  20. Luogu1039 侦探推理

热门文章

  1. iOS问题记录 - Xcode 14安装低版本iOS模拟器
  2. renderdoc 抓google地图
  3. 5.13 利用图层的矢量蒙版打造浪漫情调 [原创Ps教程]
  4. 【英语-同义词汇词组】study和research的用法及区别
  5. Java(22):Java连接Mysql数据库的操作说明
  6. 挣值最常用的计算公式
  7. 【CVPR2021】论文汇总列表--Part1
  8. MEMS传感器的下一轮技术变革
  9. 华为一员工猝死出租屋 警方初步排除他杀
  10. Flask的Jinjia2模板