OAuth2学习(实操OAuth微信登录)

news2024/11/23 21:58:46

文章目录

  • 前言
  • 1 OAuth2基本概念
  • 2 网站应用微信登录
    • 2.1 大概流程
    • 2.2 前期准备
    • 2.3 将微信登录二维码内嵌到自己页面
      • 2.3.1 后端接口编写(向前端提供参数)
      • 2.3.2 前端显示二维码页面
    • 2.4 编写回调接口
      • 2.4.1 回调接口根据code获取access_token 这个令牌
      • 2.4.2 回调接口根据access_token 这个令牌获取用户信息并且保存到数据库 实现微信登录


前言

之前有听说过OAuth,了解到其常常用于三方登录
今天来学习一下

后面的实操需要了解VUE

学习参考自博客
oauth2基本概念


1 OAuth2基本概念

首先了解oauth协议的 四个角色
1 资源拥有者(用户)


2 资源服务器
托管受保护资源的服务器,能够使用访问令牌接受和响应受保护资源请求

3 Client 客户端
代表资源所有者并经其授权发出受保护资源请求的应用程序。“客户”一词确实 不暗示任何特定的实现特征(例如, 应用程序是否在服务器、桌面或其他 设备上执行)。

4 Authorization server 授权服务器
服务器在成功 验证资源所有者并获得授权后向客户端颁发访问令牌。授权服务器和资源服务器之间的交互超出了本规范的范围。授权服务器 可以是与资源服务器相同的服务器,也可以是单独的实体。 单个授权服务器可以发布多个资源服务器接受的访问令牌。
OAuth2.0介绍 
OAuth是关于授权的开放网络标准,
允许用户授权第三方应用
访问用户存储在 另外的资源服务器上 的信息
,而不需要将用户名和密码提供给第三方应用。
认证流程如下

在这里插入图片描述

2 网站应用微信登录

2.1 大概流程

微信官方参考链接
参考链接

1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作
也就是说 最终三方应用要使用这个access_token授权令牌
通过这个access_token拿到用户存储到微信服务器上的一些信息数据

在这里插入图片描述

2.2 前期准备

1、注册
微信开放平台:https://open.weixin.qq.com
2、邮箱激活
3、完善开发者资料
4、开发者资质认证
准备营业执照,1-2个工作日审批、3005、创建网站应用
提交审核,7个工作日审批
6、内网穿透
ngrok的使用

准备好配置数据 放到properties文件中

在这里插入图片描述

wx.open.app_id=wxed9954c01bb8xxxx
wx.open.app_secret=a7482517235173ddb4083788dexxxx
//redirect_uri配置 要与 微信公众号 订阅号或者服务号上配置的域名一致
wx.open.redirect_url=http://localhost:8160/api/ucenter/wx/callback
yygh.baseUrl=http://localhost:3000

YAML格式

wx:
  open:
    app_id: wxed9954c01bbxxxx
    app_secret: a7482517235173ddb408378xxxxx
    //redirect_uri配置 要与 微信公众号 订阅号或者服务号上配置的域名一致
    redirect_url: http://localhost:8160/api/ucenter/wx/callback

创建工具类 能够快速获取配置文件中的这些相关信息
在这里插入图片描述

package com.atguigu.yygh.user.utils;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ConstantWxPropertiesUtils 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;

    @Value("${yygh.baseUrl}")
    private String yyghBaseUrl;


    public static String WX_OPEN_APP_ID;
    public static String WX_OPEN_APP_SECRET;
    public static String WX_OPEN_REDIRECT_URL;
    public static String YYGH_BASE_URL;


    @Override
    public void afterPropertiesSet() throws Exception {
        WX_OPEN_APP_ID = appId;
        WX_OPEN_APP_SECRET = appSecret;
        WX_OPEN_REDIRECT_URL = redirectUrl;
        YYGH_BASE_URL = yyghBaseUrl;
    }
}

2.3 将微信登录二维码内嵌到自己页面

2.3.1 后端接口编写(向前端提供参数)

首先编写后端接口
返回前端显示二维码所必须的参数

我们已经编写好工具类

二维码所必须的参数在配置文件中——》工具类获取——》封装返回给前端

在这里插入图片描述

官方详细文档

//微信操作的接口
@Controller
@RequestMapping("/testOauth")
public class TestOauth {


    //1 生成微信扫描二维码
    //返回生成二维码需要参数
    @GetMapping("/getLoginParam")
    @ResponseBody
    public Result genQrConnect() {
        try {
            Map<String, Object> map = new HashMap<>();
            //ID
            map.put("appid", ConstantWxPropertiesUtils.WX_OPEN_APP_ID);
            //默认值
            map.put("scope","snsapi_login");
            //回调地址  根据要求需要对其进行编码
            String wxOpenRedirectUrl = ConstantWxPropertiesUtils.WX_OPEN_REDIRECT_URL;
            wxOpenRedirectUrl = URLEncoder.encode(wxOpenRedirectUrl, "utf-8");
            map.put("redirect_uri",wxOpenRedirectUrl);
            //防止攻击
            map.put("state",System.currentTimeMillis()+"");
            return Result.ok(map);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

}

POSTman测试
在这里插入图片描述

2.3.2 前端显示二维码页面

前端如何显示二维码?
1 引入JS文件
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
2 初始化 WXLOGIN JS  
请求后端刚才编写的接口 获得参数 根据这些参数
new WxLogin对象

采用一个VUE文件的方式进行创建

官方详细文档


<template>
<div>
// 这里的按钮整合了element-ui 不想整合的话 直接写button
  <el-button type="primary" size=""  autocomplete="off" @click="weixinLogin">微信登录</el-button>

  <div id="weixinLogin"></div>
</div>

</template>

<script>
import axios from "axios";


export default {
  name: "Oauth",

  data() {
    return {}
  },

  mounted() {
    // 注册全局登录事件对象
    // window.loginEvent = new Vue();
    // // 监听登录事件
    // loginEvent.$on('loginDialogEvent', function () {
    //   document.getElementById("loginDialog").click();
    // })
    // 触发事件,显示登录层:loginEvent.$emit('loginDialogEvent')

    //初始化微信js
    const script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = 'https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'
    document.body.appendChild(script)

    // 微信登录回调处理
    // let self = this;
    // window["loginCallback"] = (name,token, openid) => {
    //   debugger
    //   self.loginCallback(name, token, openid);
    // }
  },
  methods: {

    //微信登录函数 点击后显示二维码
    weixinLogin() {

      //创建axios 准备向后端发请求
      const request = axios.create({
        baseURL: 'http://localhost:8160',  // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
        // baseURL: 'http://139.224.237.247:8081/',  // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
        timeout: 5000
      })

      //发请求 把后端返回的  生成二维码所需要的参数 给WxLogin对象
      request.get("/testOauth/getLoginParam", this.user).then(response => {
        console.log(response)
        console.log(response.data.data.appid)
        console.log(response.data.data.redirect_uri)

        var obj = new WxLogin({
          self_redirect:true,
          id: 'weixinLogin', // 需要显示的容器id
          appid: response.data.data.appid, // 公众号appid wx*******
          scope: response.data.data.scope, // 网页默认即可
          redirect_uri: response.data.data.redirect_uri, // 授权成功后回调的url
          state: response.data.data.state, // 可设置为简单的随机数加session用来校验
          style: 'black', // 提供"black"、"white"可选。二维码的样式
          href: '' // 外部css文件url,需要https
        })
      })

    },
  }
}
</script>

<style scoped>

</style>


最终测试 点击微信登录 二维码生成成功
在这里插入图片描述

2.4 编写回调接口

2.4.1 回调接口根据code获取access_token 这个令牌

当我们微信扫码确认以后  
微信会请求我们传递的回调地址  并传递一个code
我们拿到code  
准备请求微信接口换取 access_token
也就是Oauth协议中 获取 access_token 这个令牌

在这里插入图片描述

由于需要请求微信接口 导入OKHTTP工具类

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.6.0</version>
        </dependency>

官方详细文档

    //微信扫描后回调的方法
    //回调地址
    // http://localhost:8160/api/ucenter/wx/callback?
    @GetMapping("/api/ucenter/wx/callback")
    @ResponseBody
    @CrossOrigin
    public String callback(String code,String state) throws Exception {
        //第一步 获取临时票据 code
        System.out.println("code:"+code);



        //第二步 拿着code和微信id和秘钥,请求微信固定地址 ,得到两个值
        //使用code和appid以及appscrect换取access_token

		//创建OKhttpclient 封装参数请求微信系统接口  
        OkHttpClient okHttpClient = new OkHttpClient();
        log.info("从前端拿到的code是===>{}",code);



        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + ConstantWxPropertiesUtils.WX_OPEN_APP_ID
                + "&secret=" + ConstantWxPropertiesUtils.WX_OPEN_APP_SECRET + "&code=" + code + "&grant_type=authorization_code";

        Request request = new Request.Builder().url(url).build();

        Response response = okHttpClient.newCall(request).execute();

        if (response.isSuccessful()) {
            JSONObject jsonResult = JSONObject.parseObject(response.body().string());

            log.info("获取的响应结果体是===》{}", jsonResult);

            String openid = jsonResult.getString("openid");
            String access_token = jsonResult.getString("access_token");

            System.out.println("openid:   " + openid);
            System.out.println("access_token:   " + access_token);

        }


        

        return "";
 }       
前端扫码 扫码后查看后端控制台
测试 获取token成功

在这里插入图片描述

2.4.2 回调接口根据access_token 这个令牌获取用户信息并且保存到数据库 实现微信登录

拿access_token 请求用户接口 能够
返回用户的一些信息 拿这些信息和oppenid存储到数据库
实现微信登录

存到数据库的代码就自己实现吧
请求用户接口前 可以先根据oppeid(用户唯一表示)查数据库
看这个用户添加过没 有的话就不让请求就可以了 直接返回这个用户
供前端显示
  //微信扫描后回调的方法
    //回调地址
    // http://localhost:8160/api/ucenter/wx/callback?
    @GetMapping("/api/ucenter/wx/callback")
    @ResponseBody
    @CrossOrigin
    public String callback(String code,String state) throws Exception {
        //第一步 获取临时票据 code
        System.out.println("code:"+code);



        //第二步 拿着code和微信id和秘钥,请求微信固定地址 ,得到两个值
        //使用code和appid以及appscrect换取access_token
        OkHttpClient okHttpClient = new OkHttpClient();
        log.info("从前端拿到的code是===>{}",code);



        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + ConstantWxPropertiesUtils.WX_OPEN_APP_ID
                + "&secret=" + ConstantWxPropertiesUtils.WX_OPEN_APP_SECRET + "&code=" + code + "&grant_type=authorization_code";

        Request request = new Request.Builder().url(url).build();
        Response response = okHttpClient.newCall(request).execute();


            JSONObject jsonResult = JSONObject.parseObject(response.body().string());

            log.info("获取的响应结果体是===》{}", jsonResult);

            String openid = jsonResult.getString("openid");
            String access_token = jsonResult.getString("access_token");

            System.out.println("openid:   " + openid);
            System.out.println("access_token:   " + access_token);

        //第三步 拿着openid  和  access_token请求微信地址,得到扫描人信息
        String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                        "?access_token=" + access_token +
                        "&openid="+ openid;

        Request request1 = new Request.Builder().url(baseUserInfoUrl).build();
        Response response1 = okHttpClient.newCall(request1).execute();

        if (response.isSuccessful()) {
            JSONObject jsonResultuserInfo = JSONObject.parseObject(response1.body().string());

            log.info("请求用户信息获取的响应结果体是===》{}", jsonResultuserInfo);

        }

        return "";
    }    

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/457223.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据分析工具Power BI(十三):制作占比分析图表

文章目录 制作占比分析图表 一、饼图 二、环形图 三、树状图

赛题解析 | kaggle百万奖金新赛--图书墨水检测大赛

整理自kaggle平台 比赛题目 Vesuvius Challenge - Ink Detection kaggle-图书墨水检测 比赛背景 赫库兰尼姆卷轴中使用的墨水在X射线扫描中不容易显示出来。但我们发现机器学习模型可以检测到它。幸运的是&#xff0c;我们有地面实况数据。自从近300年前发现赫库兰尼姆Papyr…

【K8S系列】深入解析Service

序言 Dont count the days. Make the days count 不要数着日子。让日子过得有意义 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用来标记二级论点 Kubernetes (k8s) 是一个容器编排平…

React 组件 API

常用 React 组件 API&#xff1a; 设置状态&#xff1a;setState替换状态&#xff1a;replaceState设置属性&#xff1a;setProps替换属性&#xff1a;replaceProps强制更新&#xff1a;forceUpdate获取DOM节点&#xff1a;findDOMNode判断组件挂载状态&#xff1a;isMounted …

基础自动化测试脚本开发——Loadrunner网页系统两种创建关联函数的方法详解

前言 许多的系统都采用SessionID或SeqID等方法来标识不同的任务和数据报&#xff0c;应用在每次运行时发送的数据并不完全相同。所以&#xff0c;为了让脚本能够支持测试的需求&#xff0c;就必然要用某种机制对脚本的数据进行关联了。总之一句话&#xff1a;通过关联可以在测试…

AOD实践,modis数据下载,modis数据处理

modis数据下载-数据读取-重投影-拼接-均值 一、数据下载 1、Cygwin安装 Cygwin安装教程&#xff1a;https://blog.csdn.net/u010356768/article/details/90756742 1.2 数据采集 现提供遥感数据下载服务&#xff0c;主要是NASA数据&#xff0c;数据下载网站包括&#xff1a…

炸裂的 AutoGPT,鱼皮教你免费用!

大家好&#xff0c;我是鱼皮&#xff0c;继前段时间爆火的 ChatGPT 后&#xff0c;又一个炸裂的开源项目 Auto-GPT 出现了。 仅在最近 10 天&#xff0c;这个项目就收获了 8 万多个 star&#xff0c;目前总 star 数超过 10 万&#xff01; 那 Auto-GPT 到底是个什么玩意&#x…

一文让你熟练使用 JSONObject 和 JSONArray

依赖 导入阿里的 fastjson 依赖。 <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.78</version></dependency>类型转换 String 与 JSON 相互转换 通过 JSONObject.parseObject…

21、越狱调试

前言 调试一款应用,使用重签名方案,很容易被第三方察觉.在越狱环境中,我们可以在不污染App的情况下,对第三方程序进行动态调试 一、Reveal Reveal 是一款UI调试工具,对iOS逆向开发非常有帮助. 在Mac电脑中,安装Reveal软件: 密码 xclient.info 在手机中,安装Reveal插件打开C…

【京东】商品评价数据采集+买家评论数据+卖家评论数据采集+行业数据分析+行业数据质检分析

采集场景 京东商品详情页中的评价&#xff0c;有多个分类&#xff1a;【全部评价】、【晒图】、【视频晒单】、【追评】、【好评】、【中评】、【差评】。其中【全部评价】默认展现&#xff0c;其他需点击后展现。本文以按【差评】筛选采集为例讲解。实例网址&#xff1a;http…

MySQL-----复合查询

文章目录 前言一、基本查询回顾二、 多表查询解决多表查询的思路 三、自连接四、子查询1. 单行子查询2. 多行子查询3. 多列子查询4. 在from子句中使用子查询5. 合并查询5.1 union5.2 unoin all 总结 前言 前面的学习中,对于mysql表的查询都是对一张表进行查询,在实际开发中这远…

快速入门git(收藏篇)

大致总结&#xff1a; 本地仓库要先去github注册&#xff0c;并通过github的验证。于是本地仓库的文件均可通过协议传输至github任意一个仓库。本地文件要先传到本地仓库&#xff0c;由本地仓库传输至远程github仓库。 在详细学习git之前&#xff0c;我们先来看看Git和svn之间…

系统集成项目管理工程师 笔记(第七章:项目范围管理)

文章目录 7.1.1 项目范围管理的含义及作用7.1.2 项目范围管理的主要过程&#xff08;6个&#xff09; 7.2 编制范围管理计划和范围说明书 2687.2.1 编制范围管理计划过程所用的工具与技术7.2.2 编制范围管理计划过程的输入、输出 7.3 收集需求 2717.3.1 收集需求过程的工具与技…

java 网络编程总结

目录 一、拾枝杂谈 1.网络通信 : 2.网络 : 3.IP : 4.IPv4的ip地址分类 : 5.域名和端口 : 6.网络协议 : 二、网络编程 1.InetAddress : 1 常用方法 : 2 代码演示 : 2.Socket : 1 概述 : 2 代码演示 : eg1 : 客户端连接服务端 eg2 : 结束标记 eg3 : 网络传输文件…

Linux设置进程自启动

systemd学习 http://www.jinbuguo.com/systemd/systemctl.html https://blog.csdn.net/sinat_35815559/article/details/102867290 常用命令 立即启动一个服务&#xff1a; systemctl start xxx.service立即停止一个服务&#xff1a; systemctl stop xxx.service重启一个服…

跌倒检测和识别4:C++实现跌倒检测(含源码,可实时跌倒检测)

跌倒检测和识别4&#xff1a;C实现跌倒检测(含源码&#xff0c;可实时跌倒检测) 目录 跌倒检测和识别4&#xff1a;C实现跌倒检测(含源码&#xff0c;可实时跌倒检测) 1. 前言 2. 跌倒检测模型&#xff08;YOLOv5&#xff09; &#xff08;1&#xff09;跌倒检测模型训练 …

第14届蓝桥杯 | 冶炼金属

作者&#xff1a;指针不指南吗 专栏&#xff1a;第14届蓝桥杯真题 &#x1f43e;慢慢来&#xff0c;慢慢来&#x1f43e; 文章目录 题目代码摸索第一次 AC 5/10第二次 AC 100% 反思 题目 链接&#xff1a; 4956. 冶炼金属 - AcWing题库 小蓝有一个神奇的炉子用于将普通金属 O …

【LeetCode】数据结构刷题(2)[查找链表的中间节点]

【LeetCode】数据结构刷题&#xff08;2&#xff09; 1.题目来源2.题目描述3.解题思路4.代码展示5.类似题目练习 所属专栏&#xff1a;玩转数据结构题型 博主首页&#xff1a;初阳785 代码托管&#xff1a;chuyang785 感谢大家的支持&#xff0c;您的点赞和关注是对我最大的支持…

自动驾驶方案及相关对标

华为&#xff1a; 2021年4月18日&#xff0c;在华为智能汽车解决方案BU新品发布会上&#xff0c;华为智能汽车解决方案BU总裁王军表示&#xff0c;华为要持续加大对汽车行业的投入&#xff0c;今年在研发上的投资将达到10亿美元&#xff0c;未来每年保持30%左右增长&#xff0…

three.js的着色器(巨详细 初学者 大白话)

three.js就不过多介绍了 可以看另一篇文章 总结就是场景 相机 和 渲染器 学起来 也比较轻松 后来看到了着色器 给我整懵乐了 一会一个API 一会一个API 都没见过 然后就一点点去学习 真的是费了好大劲了 需要知道很多新东西 才能初步知道和使用着色器 当然如果只是简单的使…