前端笔记_OAuth规则机制下实现个人站点接入qq三方登录

这篇具有很好参考价值的文章主要介绍了前端笔记_OAuth规则机制下实现个人站点接入qq三方登录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前端笔记_OAuth规则机制下实现个人站点接入qq三方登录,web站点,oAuth,三方登录,aAuth2.0,node,javascript,vue2

⭐前言

大家好,我是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前端笔记_OAuth规则机制下实现个人站点接入qq三方登录,web站点,oAuth,三方登录,aAuth2.0,node,javascript,vue2

获取qq用户账号头像和openid登入
前端笔记_OAuth规则机制下实现个人站点接入qq三方登录,web站点,oAuth,三方登录,aAuth2.0,node,javascript,vue2

⭐qq三方登录流程

前提条件: 存在可访问的网站,在qq互联中心创建应用审核
友情提示:网站不可使用外部cdn,可导致审核人员查看白屏而失败

💖qq互联中心创建网页应用

填写域名资料,提交审核
前端笔记_OAuth规则机制下实现个人站点接入qq三方登录,web站点,oAuth,三方登录,aAuth2.0,node,javascript,vue2

💖配置回调地址redirect_uri

回调地址是用户使用qq登录之后调整的地址会携带code和state的参数

💖流程分析

  1. 唤起qq授权登录url
  2. 登录qq成功获取code
  3. 通过code去换取access_token
  4. 通过access_token去换取openid
  5. 通过access_token和openid去换取userinfo

前端笔记_OAuth规则机制下实现个人站点接入qq三方登录,web站点,oAuth,三方登录,aAuth2.0,node,javascript,vue2

⭐思路分解

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+'?'+path
        resolve(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}=req
        const {state}=query
        const 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}=req
        const {code}=query
        console.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}=req
        const {access_token}=query
        console.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}=req
        const {code}=query
        console.log('code',code)
        const tokenRsponse=await getToken(code)
        const tokenBody=JSON.parse(tokenRsponse.body)
        const {access_token}=tokenBody
        const 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}=req
        const {access_token,openId}=query
        console.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.href
        const data={}
        const urlArray=href.split('?')
        const urlLength=urlArray.length
        if(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)
        {
            //发送data
            window.opener.postMessage(data,'*')
            //关闭
            setTimeout(()=>{
                window.close()
            },1000)
        }
    }
    window.onload=init
</script>
</body>
</html>

vue前端qq登录的调用:

		async qqLogin () {
            try {
                const that = this
                // qq
                const res = await that.$axios
                    .post('/third-login/getAuthUrl')
                console.log('res', res)
                if (res.data && res.data.data) {
                    const resData = res.data.data
                    console.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} = res
                            if (origin.includes('yongma16.xyz')) {
                                const {code, state} = data
                                console.log('code state', code, state)
                                that.thirdLoginConfig.qCode = code
                                that.thirdLoginConfig.qState = state
                                const 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.data
                    if (access_token) {
                        this.thirdLoginConfig.qToken = access_token
                        await 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.data
                    if (openid) {
                        this.thirdLoginConfig.qOpenid = openid
                        await 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.data
                    this.registerThirdLogin()
                }
                console.log('userRes', userRes)
            } catch (e) {
                console.log('token error', e)
            }
        }

效果:

前端笔记_OAuth规则机制下实现个人站点接入qq三方登录,web站点,oAuth,三方登录,aAuth2.0,node,javascript,vue2

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!
前端笔记_OAuth规则机制下实现个人站点接入qq三方登录,web站点,oAuth,三方登录,aAuth2.0,node,javascript,vue2

👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 感谢你的阅读!文章来源地址https://www.toymoban.com/news/detail-569867.html

到了这里,关于前端笔记_OAuth规则机制下实现个人站点接入qq三方登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Day976.如何安全、快速地接入OAuth 2.0? -OAuth 2.0

    Hi,我是 阿昌 ,今天学习记录的是关于 如何安全、快速地接入OAuth 2.0? 的内容。 授权服务将 OAuth 2.0 的复杂性都揽在了自己身上,这也是授权服务为什么是 OAuth 2.0 体系的核心的原因之一。 虽然授权服务做了大部分工作,但是呢,在 OAuth 2.0 的体系里面,除了资源拥有者是

    2024年02月12日
    浏览(28)
  • 【智能交互】OPPO接入小布语音技能通关教程:个人开发者实现接口调用

    适用人群:本教程适合大赛接入小布语音技能的同学以及初次使用小布助手的开发者 本篇文章是博主弄了多次测试才勉强弄明白的,OPPO的开发文档和没有没啥区别 很多人会问:“为啥有更成熟的其他语音技能平台放着不用?” 答:“因为我在参加的比赛是由oppo主办方举办

    2024年02月16日
    浏览(144)
  • 05 - 如何安全、快速地接入OAuth 2.0?

    在第 3 节,已经讲了授权服务的流程,如果还记得的话,当时特意强调了一点,就是 授权服务将 OAuth 2.0 的复杂性都揽在了自己身上 ,这也是授权服务为什么是 OAuth 2.0 体系的核心的原因之一。 虽然授权服务做了大部分工作,但是呢,在 OAuth 2.0 的体系里面,除了资源拥有者

    2024年03月27日
    浏览(49)
  • 个人搭建部署gpt站点

    参照博客 GPT官网如果云服务器是国内厂商是墙了,如果部署到自己国内服务器需要额外设置代理,原先国人大佬搞的代理目前已经用不了了,推荐直接vercel部署一步到位。 必需国外手机号,可用国外接码平台(有免费),使用次数过多的手机号可以直接忽略,切换手机号还要人

    2024年02月22日
    浏览(33)
  • 【OAuth2系列】Spring Cloud Gateway 作为OAuth2 Client接入第三方单点登录代码实践

            在年初的时候我参与了一个项目,当时是很多家公司协同完成这个项目,其中一个公司专门负责登录这块的内容,需要我们的后端接入他们的单点登录(OAuth2 授权码模式),这块接入工作是由我来负责,我们的项目是微服务架构,经过网上各种查阅资料发现网关作为

    2024年02月04日
    浏览(50)
  • python爬虫_selenuim登录个人markdown博客站点

    大家好,我是yma16,本文分享python使用selenuim登录个人markdown博客站点。 该系列文章: python爬虫_基本数据类型 python爬虫_函数的使用 python爬虫_requests的使用 python爬虫_selenuim可视化质量分 python爬虫_django+vue3可视化csdn用户质量分 python爬虫_正则表达式获取天气预报并用echarts折线

    2024年02月16日
    浏览(35)
  • 如何使用Plex在Windows系统搭建个人媒体站点公网可访问

    用手机或者平板电脑看视频,已经算是生活中稀松平常的场景了,特别是各种碎片时间(追剧下饭、地铁上刷剧等等),看个喜欢的视频必不可少。但不知道为什么,各大影音平台总能轮流占住热播剧,还限定很多剧只能会员观看,搞得我们总有交不完的会员费。此时,拥有

    2024年02月03日
    浏览(33)
  • 基于VS编译器探测成员函数指针的调用规则,并分析MFC消息映射实现机制的局限性问题

    /* 当想继承MFC的窗口类时,如果有多重继承,则继承的窗口类顺序要特别注意(要在继承列表的首个); 否则根据MFC消息映射机制的实现方式;调用指向成员函数指针时;根据前面的规则会触发代码混淆,导致运行期错误;如下: 这个也是MFC 窗体类继承顺序的问题的根本原因

    2024年02月06日
    浏览(25)
  • 尝鲜!最新 VitePress 1 版本 + Github action,自动部署个人静态站点 SSG

    今天查看 vue 文档时,刚好看到 vue 官网宣布 VitePress 1 更新了: 然后在路上走着走着,突然想着,也许我可以把我的笔记仓库转换成在线文档(毕竟纯粹的 md 笔记,喜欢的人不多)。 同时,由于我很久之前有过这 vuepress 的使用经验,而且前段时间又复习了一下 github action,

    2024年04月08日
    浏览(44)
  • 【前端Vue】社交信息头条项目完整笔记第3篇:三、个人中心,TabBar 处理【附代码文档】

    社交媒体-信息头条项目完整开发笔记完整教程(附代码资料)主要内容讲述:一、项目初始化使用 Vue CLI 创建项目,加入 Git 版本管理,调整初始目录结构,导入图标素材,引入 Vant 组件库,移动端 REM 适配。二、登录注册准备,实现基本登录功能,登录状态提示,表单验证,验证码处理

    2024年04月16日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包