前端笔记_OAuth规则机制下实现个人站点接入qq三方登录
文章目录
- ⭐前言
- ⭐qq三方登录流程
- 💖qq互联中心创建网页应用
- 💖配置回调地址redirect_uri
- 💖流程分析
- ⭐思路分解
- ⭐技术选型+实现
- 💖技术选型:
- 💖实现
- ⭐结束

⭐前言
大家好,我是yma16,本文分享OAuth规则机制下实现个人站点接入qq三方登录。
oauth授权
OAuth是一种授权机制,用于允许用户(资源所有者)向第三方应用程序授予有限的访问权限,而不必将凭证直接提供给第三方应用程序。OAuth的目的是为了保护用户的私密数据,如社交媒体帐户、云存储、银行帐户等。它通过一个流程,将用户授权给第三方应用程序访问用户的资源,而不需要第三方应用程序获得用户的凭证信息。这样做可以减少用户数据泄露的风险。OAuth是一个开放的标准,由OAuth工作组维护,并得到许多组织的支持和使用。
oauth的发展
OAuth协议的发展历史可以追溯到2004年,当时美国国防部提出了一个名为“OpenID Connect”的开放式身份认证和授权标准,旨在解决Web 2.0中的身份认证和授权问题。OAuth1.0于2005年被RFC 5849正式标准化,OAuth2.0于2011年被RFC 6749正式标准化 。
OAuth1.0的主要特点是将用户的认证信息(如用户名和密码)与第三方应用的请求分离开来,从而提高了安全性。
OAuth2.0则在OAuth1.0基础上进一步改进,增加了更多的功能和灵活性,如授权码模式、隐式模式、密码模式等 。
效果
在个人站点实现三方qq登录
链接直达:https://yongma16.xyz
唤起三方登录url
获取qq用户账号头像和openid登入
⭐qq三方登录流程
前提条件: 存在可访问的网站,在qq互联中心创建应用审核
友情提示:网站不可使用外部cdn,可导致审核人员查看白屏而失败
💖qq互联中心创建网页应用
填写域名资料,提交审核
💖配置回调地址redirect_uri
回调地址是用户使用qq登录之后调整的地址会携带code和state的参数
💖流程分析
- 唤起qq授权登录url
- 登录qq成功获取code
- 通过code去换取access_token
- 通过access_token去换取openid
- 通过access_token和openid去换取userinfo
⭐思路分解
1.登录页面新开窗口的auth授权qq页面
2.自定义node服务去渲染回调redirect_uri,成功登录时回传url上的参数给父页面,然后用定时器关闭页面
3. 拿到code后去换取token
4. 拿到token去换取openid
5. 拿到openid去换取userinfo
6. 使用openid去注册网站用户,显示nickname网名
⭐技术选型+实现
💖技术选型:
后端:
node
前端:
vue2
后端node封装接口
💖实现
node封装接口:
api.js
const request = require('request');const loginUrl='https://graph.qq.com/oauth2.0/authorize'
const codeToTokenUrl='https://graph.qq.com/oauth2.0/token'
const openIdUrl='https://graph.qq.com/oauth2.0/me'
const userInfoUrl='https://graph.qq.com/user/get_user_info'
const appid=自己的appid
const appKey=自己的appkey
const redirect_uri=自己的回调地址const getAuthUrl=(state)=>{return new Promise(resolve=>{const params={response_type:'code',client_id:appid,redirect_uri:encodeURI(redirect_uri),state:state?state:'myblog',};const path=Object.keys(params).forEach(key=>{return `${key}=${params[key]}`}).join('&')const url=loginUrl+'?'+pathresolve(url)})
};const getToken=(code)=>{return new Promise(async ( resolve ,reject)=> {request({method: 'GET', uri: codeToTokenUrl,qs: {grant_type: 'authorization_code',client_id: appid,client_secret: appKey,code: code,redirect_uri: encodeURI(redirect_uri),fmt: 'json'}}, function (error, response) {if (!error && response.statusCode === 200) {resolve(response)} else {console.log("error",error);reject(reject)}})})
};const getOpenId=(access_token)=>{return new Promise(async ( resolve ,reject)=> {request({method: 'GET', uri: openIdUrl,qs: {access_token:access_token,fmt: 'json'}}, function (error, response) {if (!error && response.statusCode === 200) {resolve(response)} else {reject(error)}})})
};const getUserInfo=(access_token,openId)=>{return new Promise(async ( resolve ,reject)=> {request({method: 'GET', uri: userInfoUrl,qs: {access_token:access_token,oauth_consumer_key:appid,openid:openId,fmt: 'json'}}, function (error, response) {if (!error && response.statusCode === 200) {resolve(response)} else {reject(error)}})})
}module.exports={getAuthUrl,getToken,getOpenId,getUserInfo
};
node开放接口:
const hostname = 'localhost';
const port = 6677;const express = require("express");const {getAuthUrl,getToken,getOpenId,getUserInfo}=require('./service/api.js');
const app = express();app.listen(port,hostname, () => {console.log(`Server running at http://${hostname}:${port}/`);
});
// server your css as static
app.use(express.static(__dirname));
// views
const thirdLoginDir='/views/thirdLogin/';
app.get("/getAuthUrl",async (req, res) => {try{const {query}=reqconst {state}=queryconst url=await getAuthUrl(state)res.json({code:authRes.statusCode,data:url,})}catch (e) {res.json({code:0,msg:e})}
});app.get("/getToken",async (req, res) => {try{const {query}=reqconst {code}=queryconsole.log('code',code)const tokenRsponse=await getToken(code)res.json({code:tokenRsponse.statusCode,data:JSON.parse(tokenRsponse.body),})}catch (e) {res.json({code:0,msg:e})}
});app.get("/getOpenId",async (req, res) => {try{const {query}=reqconst {access_token}=queryconsole.log('access_token',access_token)const openidRes=await getOpenId(access_token)res.json({code:openidRes.statusCode,data:JSON.parse(openidRes.body)})}catch (e) {res.json({code:0,msg:e})}
});app.get("/quickGetOpenId",async (req, res) => {try{const {query}=reqconst {code}=queryconsole.log('code',code)const tokenRsponse=await getToken(code)const tokenBody=JSON.parse(tokenRsponse.body)const {access_token}=tokenBodyconst openIdRsponse=await getOpenId(access_token)res.json({code:tokenRsponse.statusCode,data:JSON.parse(openIdRsponse.body)})}catch (e) {res.json({code:0,msg:e})}
});app.get("/getUserInfo",async (req, res) => {try{const {query}=reqconst {access_token,openId}=queryconsole.log('access_token openId',access_token,openId)const userInfoRes=await getUserInfo(access_token,openId)res.json({code:userInfoRes.statusCode,data:JSON.parse(userInfoRes.body)})}catch (e) {res.json({code:0,msg:e})}
});app.get("/qq_login_callback", (req, res) => {res.sendFile(__dirname + thirdLoginDir+"qqLoginCallback.html");
});
app.get("/azure_login_callback", (req, res) => {res.sendFile(__dirname + thirdLoginDir+"azureLoginCallback.html");
});
回调html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>qqLoginCallback</title>
</head>
<body>
qq login success!
<script type="application/javascript">function init() {console.log('qq success login')console.log('window.location.href',window.location.href)const href=window.location.hrefconst data={}const urlArray=href.split('?')const urlLength=urlArray.lengthif(urlLength>1){urlArray[urlLength-1].split('&').forEach(item=>{const itemArray=item.split('=')const key=itemArray[0]const value=itemArray[1]data[key]=value})}if(window.opener){//发送datawindow.opener.postMessage(data,'*')//关闭setTimeout(()=>{window.close()},1000)}}window.onload=init
</script>
</body>
</html>
vue前端qq登录的调用:
async qqLogin () {try {const that = this// qqconst res = await that.$axios.post('/third-login/getAuthUrl')console.log('res', res)if (res.data && res.data.data) {const resData = res.data.dataconsole.log('resData', resData)if (resData ) {let url = resData console.log('url', url)const openHandle = window.open(url, 'width:800px;height:700px', '_black')console.log('openHandle', openHandle)window.onmessage = async (res) => {const {origin, data} = resif (origin.includes('yongma16.xyz')) {const {code, state} = dataconsole.log('code state', code, state)that.thirdLoginConfig.qCode = codethat.thirdLoginConfig.qState = stateconst tokenRes = await that.getAccessToken(code)console.log('tokenRes', tokenRes)}}}}return new Promise(resolve => {resolve(true)})} catch (e) {return new Promise((resolve, reject) => {reject(e)})}},async getAccessToken (code) {try {const tokenUrl = '/third-login/getToken'const params = {code}const tokenRes = await this.$axios.get(tokenUrl, {params})console.log('tokenRes', tokenRes)if (tokenRes) {const {access_token, expires_in, refresh_token} = tokenRes.data.dataif (access_token) {this.thirdLoginConfig.qToken = access_tokenawait this.getOpenId(access_token)}}} catch (e) {console.log('token error', e)}},async getOpenId (token) {try {const tokenUrl = '/third-login/getOpenId'const params = {access_token: token}const openIdRes = await this.$axios.get(tokenUrl, {params})console.log('openIdRes', openIdRes)if (openIdRes) {const {openid} = openIdRes.data.dataif (openid) {this.thirdLoginConfig.qOpenid = openidawait this.getQUserinfo(this.thirdLoginConfig.qToken, openid)}}} catch (e) {console.log('token error', e)}},async getQUserinfo (token, openId) {try {const userInfoUrl = '/third-login/getUserInfo'const params = {access_token: token,openId: openId}const userRes = await this.$axios.get(userInfoUrl, {params})if (userRes) {this.thirdLoginConfig.qUserInfo = userRes.data.datathis.registerThirdLogin()}console.log('userRes', userRes)} catch (e) {console.log('token error', e)}}
效果:
⭐结束
本文分享到这结束,如有错误或者不足之处欢迎指出!
👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 感谢你的阅读!
相关文章:

前端笔记_OAuth规则机制下实现个人站点接入qq三方登录
文章目录 ⭐前言⭐qq三方登录流程💖qq互联中心创建网页应用💖配置回调地址redirect_uri💖流程分析 ⭐思路分解⭐技术选型实现💖技术选型:💖实现 ⭐结束 ⭐前言 大家好,我是yma16,本…...

huggingface新作品:快速和简便的训练模型
AutoTrain Advanced是一个用于训练和部署最先进的机器学习模型的工具。它旨在提供更快速、更简便的方式来进行模型训练和部署。 安装 您可以通过PIP安装AutoTrain-Advanced的Python包。请注意,为了使AutoTrain Advanced正常工作,您将需要python > 3.…...

利用鸿鹄优化共享储能的SCADA 系统功能,赋能用户数据自助分析
摘要 本文主要介绍了共享储能的 SCADA 系统大数据架构,以及如何利用鸿鹄来更好的优化 SCADA 系统功能,如何为用户进行数据自助分析赋能。 1、共享储能介绍 说到共享储能,可能不少朋友比较陌生,下面我们简单介绍一下共享储能的价值…...
noSQL语句练习
Redis练习题 string list hash结构中,每个至少完成5个命令,包含插入 修改 删除 查询,list 和hash还需要增加遍历的操作命令 1、 string类型数据的命令操作: (1) 设置键值: 127.0.0.1:63…...

Spring:Bean生命周期
Bean 生命周期生命周期 Bean 生命周期是 bean 对象从创建到销毁的整个过程。 简单的 Bean 生命周期的过程: 1.实例化(调用构造方法对 bean 进行实例化) 2.依赖注入(调用 set 方法对 bean 进行赋值) 3.初始化(手动配置 xml 文件中 bean 标签的 init-method 属性值,来指…...

Vue自定义指令
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。 需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。 自定义指令函数式v-big: &l…...

SpringBoot+JWT实现单点登录解决方案
一、什么是单点登录? 单点登录是一种统一认证和授权机制,指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的系统,不需要重新登录验证。 单点登录一般用于互相授信的系统,实现单一位置登录,其他信任的…...

中国国债发行数据集(2002-2023)
国债是由国家发行的债券,由于国债的发行主体是国家,所以它具有最高的信用度,被公认为是最安全的投资工具。国债按照交易市场的不同分为三类,即银行间市场国债、交易所市场国债和柜台市场国债;按照交易方式的不同分为三…...

曲师大2023大一新生排位赛-C.String题解
C.String 题目描述 众所周知,许师哥精通字符串。 一天,许师哥意外的获得了一个字符串,但他发现这个字符串并不是一个回文串,因此他非常生气。于是他决定从这个字符串中删除若干个字符使得 剩余的字符串为一个回文串。 回想回文串…...

Linux Ubuntu安装RabbitMQ服务
文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…...
什么是测试用例?如何设计?
在学习或者实际的测试工作中经常都会提到“测试用例”这个词,没错,测试用例是测试工作的核心,不管要做的是什么样的测试,在真正动手执行测试之前,我们都需要先根据软件需求来设计测试用例,之后再依据设计好…...

Maven —— 项目管理工具
前言 在这篇文章中,荔枝会介绍如何在项目工程中借助Maven的力量来开发,主要涉及Maven的下载安装、环境变量的配置、IDEA中的Maven的路径配置和信息修改以及通过Maven来快速构建项目。希望能对需要配置的小伙伴们有帮助哈哈哈哈~~~ 文章目录 前言 一、初…...
Ubuntu 命令行编辑文件后如何保存退出
在 Ubuntu 命令行中编辑文件后,可以使用以下步骤保存并退出: 按下键盘上的 Ctrl 键和 X 键组合,以退出编辑模式。如果文件已更改,你将看到提示,询问是否保存更改。按下 Y 键来确认保存更改,或按下 N 键取消…...

AHB协议理解
从小父亲就教育我,做一个对社会有用的人! 目录 Chapter1 AHB Block Diagram Ginput signal lnput signals Output Signal Chapter3 Transfers AHB接口Overview Chapter6 Data Buses HWDATA HRDATA Chapter1 Introduction AHB: Advanced High-performanc…...

【UE5 多人联机教程】01-创建主界面
目录 工程地址 步骤 参考链接 工程地址 GitHub - UE4-Maple/C_MP_Lobby: 多人大厅教程项目 步骤 1. 先新建一个工程 2. 将下载的工程中的Plugins目录拷贝到自己新建的工程下 3. 打开工程,新建一个游戏实例 这里命名为“GI_Main” 在项目设置中设置游戏实例类为…...

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(基本语法 五)
Styles装饰器:定义组件重用样式 如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,我们推出了可以提炼公共样式进行复用的装饰器St…...

React(3)
1.案例选项卡 import React, { Component } from reactexport default class App extends Component {state{tabList:[{id:1,text:"电影"},{id:2,text:"影院"},{id:3,text:"我的"}]}render() {return (<div><ul>{this.state.tabList…...

LangChain大型语言模型(LLM)应用开发(三):Chains
LangChain是一个基于大语言模型(如ChatGPT)用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互&#x…...

FPGA——点亮led灯
文章目录 一、实验环境二、实验任务三、实验过程3.1 编写verliog程序3.2 引脚配置 四、仿真4.1 仿真代码4.2仿真结果 五、实验结果六、总结 一、实验环境 quartus18.1 vscode Cyclone IV开发板 二、实验任务 每间隔1S实现led灯的亮灭,实现流水灯的效果。 三、实…...

idea创建spark教程
1、环境准备 java -version scala -version mvn -version spark -version 2、创建spark项目 创建spark项目,有两种方式;一种是本地搭建hadoop和spark环境,另一种是下载maven依赖;最后在idea中进行配置,下面分别记录两…...

极智项目 | 基于PyQT+Whisper实现的语音识别软件设计
这是一个基于OpenAI的Whisper模型的语音识别应用程序,使用PyQt5构建了简洁直观的用户界面。该应用支持多语言识别,特别优化了中文识别体验。 项目下载:链接 功能特点 简洁现代的深色主题界面支持多语言识别(中文、英语、日语等…...
win中将pdf转为图片
0 资料 博客 1 正文 直接使用这个软件即可https://sourceforge.net/projects/pkpdfconverter/...
leetcode47.全排列II:HashSet层去重与used数组枝去重的双重保障
一、题目深度解析与重复排列问题 题目描述 给定一个可能包含重复数字的数组nums,返回其所有不重复的全排列。解集不能包含重复的排列,且排列可以按任意顺序返回。例如: 输入:nums [1,1,2]输出:[[1,1,2],[1,2,1],[2…...

机器学习:决策树和剪枝
本文目录: 一、决策树基本知识(一)概念(二)决策树建立过程 二、决策树生成(一)ID3决策树:基于信息增益构建的决策树。(二)C4.5决策树(三ÿ…...
CMake 为 Debug 版本的库或可执行文件添加 d 后缀
在使用 CMake 构建项目时,我们经常需要区分 Debug 和 Release 构建版本。一个常见的做法是为 Debug 版本的库或可执行文件添加后缀(如 d),例如 libmylibd.so 或 myappd.exe。 本文将介绍几种在 CMake 中实现为 Debug 版本自动添加 d 后缀的方法。 方法一:使用 CMAKE_DEBU…...
C#中的密封类与静态类:特性、区别与应用实例
深入解析两类特殊类的设计哲学与实战应用 在面向对象编程领域中,C#提供了多种特殊的类类型以满足不同设计需求。其中密封类(sealed class)和静态类(static class)是最常用的两种特殊类类型。本文将从设计理念、应用场…...
gvim比较两个文件不同并合并差异
使用 gvim 比较两个文件的不同: 方式一,使用 gvim 同时打开两个待比较的文件。 比较通用方式是采用 gvim -d 选项,具体命令,如下: gvim -d <file1> <file2>方式二,先用 gvim 打开一个文件&am…...
三类 Telegram 账号的风控差异分析与使用建议
在使用 Telegram 过程中,很多用户会遇到账号被限制、封禁、加群失败等问题。除了操作行为外,账号本身的注册方式、活跃时间、环境匹配程度也会直接影响风控等级。 本篇文章从账号风控角度出发,分析三类常见 Telegram 账号的特点与适用环境&am…...

全球知名具身智能/AI机器人实验室介绍之AI FACTORY基于慕尼黑工业大学
全球知名具身智能/AI机器人实验室介绍之AI FACTORY基于慕尼黑工业大学 TUM AI FACTORY,即KI.FABRIK,是德国慕尼黑工业大学(TUM)在巴伐利亚州推出的一个旗舰项目,旨在打造未来工厂,将传统工厂转变为由人工智…...

如何在电脑上轻松访问 iPhone 文件
我需要将 iPhone 下载文件夹中的文件传输到 Windows 11 电脑上。我该怎么做?我可以在 Windows 11 上访问 iPhone 下载吗? 由于 iOS 和 Windows 系统之间的差异,在 PC 上访问 iPhone 文件似乎颇具挑战性。然而,只要使用正确的工具…...