【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【18】认证服务02—微博社交登录

news2024/12/26 9:33:22

持续学习&持续更新中…

守破离


【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【18】认证服务02—微博社交登录

  • 微博社交登录
    • 图示原理
    • 前置准备
    • 实现流程
    • 完整代码
  • 参考

微博社交登录

在这里插入图片描述

OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。

OAuth2.0:对于用户相关的 OpenAPI(例如获取用户信息,动态同步,照片,日志,分享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。

Oauth2.0:授权通过后,使用 code 换取 access_token,然后去访问任何开放 API

  • code 用后即毁
  • access_token 在几天内是一样的
  • uid 永久固定

官方版流程

在这里插入图片描述

图示原理

在这里插入图片描述


在这里插入图片描述

前置准备

进入微博开放平台

在这里插入图片描述

登陆微博,进入微连接,选择网站接入

在这里插入图片描述

在这里插入图片描述

创建自己的应用

在这里插入图片描述

进入高级信息,填写授权回调页的地址,我们可以在开发阶段进行测试了

在这里插入图片描述

在这里插入图片描述

添加测试账号(选做)

在这里插入图片描述

进入文档,按照流程测试社交登陆:

  • https://open.weibo.com/wiki/%E9%A6%96%E9%A1%B5
  • https://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E
  • https://open.weibo.com/wiki/Oauth2/access_token

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

实现流程

在这里插入图片描述

redirect_uri 就是配的 授权回调页
client_id 就是 App Key

在前端引导需要授权的用户到如下地址:

<li>
    <a href="https://api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI">
        <img style="width: 50px;height: 18px" src="/static/login/JD_img/weibo.png"/>
    </a>
</li>

如果用户同意授权,页面跳转至 YOUR_REGISTERED_REDIRECT_URI/?code=CODE:在我们的项目里就是:http://auth.gulimall.com/oauth2.0/weibo/success?code=47b9213cf5da2b038ee98fc52f34021d

    @GetMapping("/oauth2.0/weibo/success")
    public String weibo(@RequestParam("code") String code) throws Exception {}

拿code换取Access Token:https://api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE
其中client_id=App Key & client_secret=App Secret

        Map<String, String> headers = new HashMap<>();
        Map<String, String> bodys = new HashMap<>();
        bodys.put("client_id", "3276999101");
        bodys.put("client_secret", "452bbefff4680ac8554b97799a8c12cb");
        bodys.put("grant_type", "authorization_code");
        bodys.put("redirect_uri", "http://auth.gulimall.com/oauth2.0/weibo/success");
        bodys.put("code", code);
        //1、根据code换取accessToken;
        HttpResponse response = HttpUtils.doPost(
                "https://api.weibo.com",
                "/oauth2/access_token",
                headers,
                null,
                bodys);

        //2、处理
        if (response.getStatusLine().getStatusCode() == 200) { // 获取到了 accessToken
            String json = EntityUtils.toString(response.getEntity());
            SocialUserAccessToken accessToken = JSON.parseObject(json, SocialUserAccessToken.class);
            String uid = accessToken.getUid();
            // 通过uid就知道当前是哪个社交用户
            //1)、当前用户如果是第一次进网站,进行自动注册(为当前社交用户生成一个会员信息账号,以后这个社交账号就对应指定的会员账号)
            //登录或者注册这个社交用户
            //2)、登录成功就跳回首页
            return "redirect:http://gulimall.com";
        }

拿到Access Token就可以获取用户信息:https://open.weibo.com/apps/3276999101/privilege

在这里插入图片描述

比如:根据用户ID获取用户信息:https://open.weibo.com/wiki/2/users/show

在这里插入图片描述

 Map<String,String> query = new HashMap<>();
 query.put("access_token", accessToken);
 query.put("uid",uid);
 HttpResponse response = 
         HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json", new HashMap<>(), query);
 if(response.getStatusLine().getStatusCode() == 200){
     //查询成功
     String json = EntityUtils.toString(response.getEntity());
     JSONObject jsonObject = JSON.parseObject(json);
     //获取用户信息
     String name = jsonObject.getString("name");
     String gender = jsonObject.getString("gender");
 }

拿到用户信息就可以判断当前社交用户是否已经登录过系统,快速进行注册/登录。

完整代码

<a href="https://api.weibo.com/oauth2/authorize?client_id=xxxx&response_type=code&redirect_uri=xxxx">
    <img style="width: 50px;height: 18px" src="/static/login/JD_img/weibo.png"/>
</a>
    /**
     * 微博用户授权成功回调
     * http://auth.gulimall.com/oauth2.0/weibo/success?code=7d42ee3197927a8807460280d86152cd
     * 拿到code换取Access Token:其中client_id=App Key&client_secret=App Secret
     * POST:https://api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE
     * 拿到Access Token就可以获取用户信息:
     * https://api.weibo.com/2/users/show.json?uid=xxxx&access_token=xxxx
     */

    @GetMapping("/oauth2.0/weibo/success")
    public String weibo(@RequestParam("code") String code) throws Exception {
        Map<String, String> headers = new HashMap<>();
        Map<String, String> bodys = new HashMap<>();
        bodys.put("client_id", "3276999101");
        bodys.put("client_secret", "452bbefff4680ac8554b97799a8c12cb");
        bodys.put("grant_type", "authorization_code");
        bodys.put("redirect_uri", "http://auth.gulimall.com/oauth2.0/weibo/success");
        bodys.put("code", code);
        //1、根据code换取accessToken;
        HttpResponse response = HttpUtils.doPost(
                "https://api.weibo.com",
                "/oauth2/access_token",
                headers,
                null,
                bodys);
        if (response.getStatusLine().getStatusCode() == 200) {
            //2、获取到了 socialUserAccessToken 进行处理
            String json = EntityUtils.toString(response.getEntity());
            SocialUserAccessToken socialUserAccessToken = JSON.parseObject(json, SocialUserAccessToken.class);
//            String uid = socialUserAccessToken.getUid();
            // 通过uid就知道当前是哪个社交用户
            //1)、当前用户如果是第一次进网站,进行自动注册(为当前社交用户生成一个会员信息账号,以后这个社交账号就对应指定的会员账号)
            R r = memberFeignService.socialLogin(socialUserAccessToken);
            if(r.getCode() == BizCodeEnume.SUCCESS.getCode()) {
                //登录或者注册这个社交用户
                //2)、登录成功就跳回首页
                return "redirect:http://gulimall.com";
            }
        }
        return "redirect:http://auth.gulimall.com/login.html";
    }
    @Override
    public MemberEntity login(SocialUserAccessToken socialUser) {
        //登录和注册合并逻辑

        String uid = socialUser.getUid(); // 社交网站用于标识用户的唯一ID
        String accessToken = socialUser.getAccess_token();

        //1、判断当前社交用户是否已经登录过系统;
        MemberDao memberDao = this.baseMapper;
        MemberEntity memberEntity = memberDao.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid));

        long expiresIn = socialUser.getExpires_in();

        if (memberEntity != null) {
            //这个用户已经注册过
            MemberEntity update = new MemberEntity();
            update.setAccessToken(accessToken);
            update.setExpiresIn(expiresIn);
            memberDao.updateById(update);

            memberEntity.setAccessToken(accessToken);
            memberEntity.setExpiresIn(expiresIn);
            return memberEntity;
        } else {
            //2、没有查到当前社交用户对应的记录我们就需要注册一个(将social_id和我们系统的会员id关联起来)
            MemberEntity regist = new MemberEntity();

            try {
                //3、查询当前社交用户的社交账号信息(昵称,性别等)
                Map<String, String> query = new HashMap<>();
                query.put("access_token", accessToken);
                query.put("uid", uid);
                HttpResponse response = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json", new HashMap<>(), query);
                if (response.getStatusLine().getStatusCode() == 200) {
                    //查询成功
                    String json = EntityUtils.toString(response.getEntity());
                    JSONObject jsonObject = JSON.parseObject(json);
                    //获取用户信息
                    String name = jsonObject.getString("name");
                    String gender = jsonObject.getString("gender");
                    //........
                    regist.setNickname(name);
                    regist.setGender("m".equals(gender) ? 1 : 0);
                    //........
                }
            } catch (Exception e) {}

            regist.setSocialUid(socialUser.getUid());
            regist.setAccessToken(accessToken);
            regist.setExpiresIn(expiresIn);

            memberDao.insert(regist);

            return regist;
        }
    }

参考

雷丰阳: Java项目《谷粒商城》Java架构师 | 微服务 | 大型电商项目.


本文完,感谢您的关注支持!


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

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

相关文章

Python-Tkinter+Logging+Sqlserver项目结合

参考文章&#xff1a; https://www.jb51.net/article/283745.htm 目录&#xff1a; common(文件夹) – base.py – config_reader.py – dosqlserver.py – log.py txt&#xff08;空文件夹&#xff0c;后面会自动生成txt文件在该文件夹下面&#xff09; 1.txt 2.txt env.…

html+js+css美观好看的动态404界面

中间的那一段话&#xff08;root开头的那一句&#xff09;是逐字输出的 那段话显示完后&#xff0c;自动显示超大号字体404 来都来了点个赞&#xff0c;关注一下呗&#x1f604;&#xff0c;本人发誓&#xff1a;你关注我&#xff0c;马上关注你 界面 源码在图片下面…

【ONE·Linux || 高级IO(一)】

总言 主要内容&#xff1a;介绍五种IO模型的基本概念、学习IO多路转接&#xff08;select、poll编程模型&#xff09;。       文章目录 总言1、问题引入1.1、网络通信与IO1.2、五种IO模型1.2.1、举例引入1.2.2、IO模型具体含义介绍1.2.2.1、阻塞式IO1.2.2.2、非阻塞轮询检…

什么是带有 API 网关的代理?

带有 API 网关的代理服务显著提升了用户体验和性能。特别是对于那些使用需要频繁创建和轮换代理的工具的用户来说&#xff0c;使用 API 可以节省大量时间并提高效率。 了解 API API&#xff0c;即应用程序编程接口&#xff0c;是服务提供商和用户之间的连接网关。通过 API 连接…

智能数字人系统的技术难点

数字人系统&#xff0c;也称为智能数字人系统或虚拟数字人系统&#xff0c;是指利用人工智能技术构建的虚拟人物形象&#xff0c;能够与人进行自然交互的系统。数字人系统涉及多项技术&#xff0c;其开发和应用存在以下技术难点。北京木奇移动技术有限公司&#xff0c;专业的软…

KES数据库实践指南:探索KES数据库的事务隔离级别

并发控制 并发控制的重要性 并发控制是数据库管理系统中的一个核心概念&#xff0c;它确保在多用户环境中&#xff0c;对数据库的并发访问不会破坏数据的完整性和一致性。 当多个用户同时对数据库进行读写操作时&#xff0c;如果缺乏有效的并发控制机制&#xff0c;可能会导致数…

HexPlane: A Fast Representation for Dynamic Scenes(总结图)

图1。用于动态三维场景的 Hex刨面。我们没有从深度 MLP 中回归颜色和不透明度&#xff0c;而是通过 HexPlann 显式地计算时空点的特征。配对一个微小的 MLP&#xff0c;它允许以上100倍加速匹配的质量。 图2。方法概述。Hex刨包含六个特征平面&#xff0c;跨越每对坐标轴(例如…

ctfshow web sql注入 web242--web249

web242 into outfile 的使用 SELECT ... INTO OUTFILE file_name[CHARACTER SET charset_name][export_options]export_options:[{FIELDS | COLUMNS}[TERMINATED BY string]//分隔符[[OPTIONALLY] ENCLOSED BY char][ESCAPED BY char]][LINES[STARTING BY string][TERMINATED…

Python 生成Md文件带超链 和 PDF文件 带分页显示内容

software.md # -*- coding: utf-8 -*- import os f open("software.md", "w", encoding"utf-8") f.write(内部测试版2024 MD版\n) for root, dirs, files in os.walk(path): dax os.path.basename(root)if dax "":print("空白…

UNIAPP_顶部导航栏右侧添加uni-icons图标,并绑定点击事件,自定义导航栏右侧图标

效果 1、导入插件 uni-icons插件&#xff1a;https://ext.dcloud.net.cn/plugin?nameuni-icons 复制 uniicons.ttf 文件到 static/fonts/ 下 仅需要那个uniicons.ttf文件&#xff0c;不引入插件、单独把那个文件下载到本地也是可以的 2、配置页面 "app-plus":…

Hi3861 OpenHarmony嵌入式应用入门--TCP Server

本篇使用的是lwip编写tcp服务端。需要提前准备好一个PARAM_HOTSPOT_SSID宏定义的热点&#xff0c;并且密码为PARAM_HOTSPOT_PSK LwIP简介 LwIP是什么&#xff1f; A Lightweight TCP/IP stack 一个轻量级的TCP/IP协议栈 详细介绍请参考LwIP项目官网&#xff1a;lwIP - A Li…

Ollama+OpenWeb UI搭建最简单的大模型交互界面

Open WebUI是一个专为大型语言模型&#xff08;LLMs&#xff09;设计的Web用户界面。这个界面提供了一个直观、响应迅速且易于使用的平台&#xff0c;使用户能够与本地运行的语言模型进行交互&#xff0c;就像与云服务中的模型交互一样。可以非常方便的调试、调用本地模型。你能…

Linux运维之管道符、重定向与环境变量

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 目录 一、输入输出重定向 二、管道命令符 三、命令行的通配符 四、常用的转义字符 五、重要的环境变量 致谢 一、输入输出重定向 输入重定向是…

快速下载!Windows 7旗舰版系统:集成所有补丁!

微软对Windows7系统停止支持后&#xff0c;Windows7设备不再收到安全补丁程序、修补程序。尽管如此&#xff0c;许多用户仍然认为Windows7是最好用、最经典的系统。有用户就特别喜欢Windows7旗舰版系统&#xff0c;那么接下来系统之家小编为大家带来的全补丁版本的Windows7系统…

C++精解【10】

文章目录 读写文件概述example csv读文件读取每个字段读取机器学习数据库iris constexpr函数GMP大整数codeblock环境配置数据类型函数类 EigenminCoeff 和maxCoeffArray类 读写文件 概述 fstream typedef basic_fstream<char, char_traits<char>> fstream;此类型…

STM32基本定时器、通用定时器、高级定时器区别

一.STM32基本定时器、通用定时器、高级定时器区别 STM32系列微控制器中的定时器资源分为基本定时器&#xff08;Basic Timer&#xff09;、通用定时器&#xff08;General Purpose Timer&#xff09;和高级定时器&#xff08;Advanced Timer&#xff09;三类&#xff0c;它们在…

类似Jira的在线项目管理软件有哪些?10 个主流的Jira替代方案

10 个 Jira 替代方案&#xff1a;PingCode、Worktile、Teambition、Redmine、Asana、monday.com、Zoho Projects、思码逸、Notion、Airtable。 Jira 是一款流行的项目管理工具&#xff0c;专为产品开发团队而设计。虽然它是一种多功能解决方案&#xff0c;几乎适用于任何类型的…

四、(1)网络爬虫入门及准备工作(爬虫及数据可视化)

四、&#xff08;1&#xff09;网络爬虫入门及准备工作&#xff08;爬虫及数据可视化&#xff09; 1&#xff0c;网络爬虫入门1.1 百度指数1.2 天眼查1.3 爬虫原理1.4 搜索引擎原理 2&#xff0c;准备工作2.1 分析爬取页面2.2 爬虫拿到的不仅是网页还是网页的源代码2.3 爬虫就是…

html+js+css登录注册界面

拥有向服务器发送登录或注册数据并接收返回数据的功能 点赞关注 界面 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>Login and Registration Form</title> <style> * …

2024“国培“来也UiBot6.0 RPA数字机器人开发综合应用

前言 (本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~) 国培笔记: 依次读取数组中每个元素 输出调试信息 [ value=[ "vivian", value[0] "老师", "上午好,O(∩_∩)O哈哈~" ], v…