当前位置: 首页 > news >正文

Java 实现集成 Google 邮箱第三方登录实践

在这里插入图片描述

文章目录

  • 前言
  • 前期准备
    • 配置客户端 ID 和重定向 URL
    • 配置 OAuth 权限请求页面
  • 登录流程
    • 前端演示代码
    • 后端演示代码
  • 总结
  • 个人简介

前言

  • Google OAuth 2.0 是其中一种常见的第三方登录方式,广泛应用于各类网站和应用程序。通过 Google OAuth 2.0,用户可以使用其 Google 账户轻松登录第三方网站,而不必创建额外的账户。本文将介绍如何集成 Google OAuth 2.0 服务,实现用户在第三方网站上的登录。

前期准备

配置客户端 ID 和重定向 URL

  • 访问 Google API Console 获取 OAuth 2.0 凭据。点击左侧边栏的“Credentials”选项,然后创建一个客户端 ID(OAuth client ID)。

  • 选择你的应用类型,可以选择 Web 站点、Android、或者 IOS 应用等,这取决于你的业务。接着在 “Authorized JavaScript origins” 这一栏目,填写你的网站域名即可,如果是本地调试的话,通常设置为http://localhost,如果有端口,加一个端口名,如 http://localhost:8000,这里的目的是让谷歌知道你网站托管的 HTTP 来源。然后在“Authorized redirect URIs”这一栏目,填写你的重定向地址,一般是你的后端登录路径。

  • 上文相关的选项都配置好以后,点击“CREATE”按钮来保存并生成客户端 ID(Client ID) 和客户端密钥(Client secret)。

配置 OAuth 权限请求页面

  • 点击左侧列表的“OAuth consent srceen” 选项,创建一个应用。

  • 填写应用的基本信息,比如名字、邮箱、域名等。这个页面的信息,会显示在弹出的确认授权登录框中,可帮助最终用户了解你是谁并与你联系。

  • 配置可访问的权限,将权限勾选后保存即可。

  • 添加测试账户,也就是在未正式上线之前,可以进行 OAuth 2.0 登录的邮箱账。

登录流程

前端演示代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Google Login</title><script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<h2>Google 登录示例</h2>
<button id="googleSignInButton">使用 Google 登录</button><script>document.getElementById('googleSignInButton').onclick = function () {// Google OAuth 2.0 URLconst clientId = '994578547547-gc6XXXX0vp9hl.apps.googleusercontent.com';  // 替换为你的Google客户端IDconst redirectUri = 'http://localhost:8000/api/google/login';  // 替换为后端的回调登录URIconst scope = 'email profile';const responseType = 'code';const googleAuthUrl = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=${responseType}&scope=${scope}`;// 重定向到 Google OAuth 2.0 授权页面window.location.href = googleAuthUrl;};
</script>
</body>
</html>

后端演示代码

  • Maven 依赖
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId></dependency>
google:token-apply-url: https://oauth2.googleapis.com/tokenuserinfo-url: https://www.googleapis.com/oauth2/v3/userinfooauth2:client-id: 994578547547-gc6uXXXXjtpk0vp9hl.apps.googleusercontent.comclient-secret: GOCSPX-nWFVXXXXFImvw3iHLNkR@Api(tags = "谷歌服务相关请求")
@RestController
@RequestMapping("/api/google")
@RequiredArgsConstructor
public class GoogleController {@Value("${google.oauth2.client-id}")private String clientId;@Value("${google.oauth2.client-secret}")private String clientSecret;@Value("${google.token-apply-url}")private String tokenEndpoint;@Value("${google.userinfo-url}")private String userInfoEndpoint;private final RestTemplate restTemplate;private final TokenProvider tokenProvider;private final UserDetailsService userDetailsService;private final UserService userService;private final SecurityProperties properties;private final OnlineUserService onlineUserService;@AnonymousGetMapping("/login")public ResponseEntity<Object> handleGoogleLogin(@RequestParam("code") String authorizationCode, HttpServletRequest req) {// Step 1: 用授权码获取 Access TokenMultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add("client_id", clientId);params.add("client_secret", clientSecret);params.add("code", authorizationCode);params.add("redirect_uri", "http://localhost:8000/api/google/login");params.add("grant_type", "authorization_code");HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);ResponseEntity<Map> response = restTemplate.postForEntity(tokenEndpoint, request, Map.class);String accessToken = (String) response.getBody().get("access_token");// Step 2: 用 Access Token 获取用户信息HttpHeaders userInfoHeaders = new HttpHeaders();userInfoHeaders.setBearerAuth(accessToken);HttpEntity<String> userInfoRequest = new HttpEntity<>(userInfoHeaders);ResponseEntity<Map> userInfoResponse = restTemplate.exchange(userInfoEndpoint, HttpMethod.GET, userInfoRequest, Map.class);Map<String, Object> userInfo = userInfoResponse.getBody();String googleId = (String) userInfo.get("sub");String email = (String) userInfo.get("email");String name = (String) userInfo.get("name");String picture = (String) userInfo.get("picture");// 用户登录逻辑、并返回用户信息、会话信息}
}

总结

  • 通过集成 Google OAuth 2.0 服务,第三方网站可以实现简单、快捷且安全的用户登录方式。OAuth 2.0 的流程保障了用户的隐私安全,不需要将敏感信息(如密码)提供给第三方应用。同时,使用 Google 登录可以减少用户的注册步骤,提升用户体验。

个人简介

👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.

🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。

🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。

💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。

🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。

📖 保持关注我的博客,让我们共同追求技术卓越。

相关文章:

Java 实现集成 Google 邮箱第三方登录实践

文章目录 前言前期准备配置客户端 ID 和重定向 URL配置 OAuth 权限请求页面 登录流程前端演示代码后端演示代码 总结个人简介 前言 Google OAuth 2.0 是其中一种常见的第三方登录方式&#xff0c;广泛应用于各类网站和应用程序。通过 Google OAuth 2.0&#xff0c;用户可以使用…...

人人都在学的智能体(AI Agent),带你轻松入门!

一、智能体初认知 AI 智能体&#xff08;英文&#xff1a;AI Agent&#xff09;究竟是个啥 先讲个故事 想象一下&#xff0c;你有一个特别能干的虚拟助手&#xff0c;我们叫他小明。小明不是普通人&#xff0c;他是一个智能体&#xff0c;就像一个超级版的 Siri 或者小爱同学&…...

如何在Windows环境下开启Kibana的非localhost访问

Kibana是一个开源的分析和可视化平台&#xff0c;用于探索和可视化Elasticsearch数据。默认情况下&#xff0c;Kibana仅允许在本地访问&#xff0c;但通过一些简单的配置更改&#xff0c;你可以允许远程访问。在本文中&#xff0c;我们将介绍如何在Windows环境下开启Kibana的非…...

蓝桥杯 单片机 DS1302和DS18B20

DS1302 时钟 时钟试题 常作为实验室考核内容 控制三个引脚 P17 时钟 P23输入 P13复位 其他已经配置好 寄存器原理 定位地址 0x80地址 固定格式 0x57 5*107*1 57 小时写入格式 不同 首位区分 A上午 P下午 0为24小时制 1为12小时制 写入8小时 0x87 //1000 7 十二小时制 7…...

前端css-媒体查询@media以及常见使用例子

媒体查询&#xff08;media&#xff09;介绍 媒体查询&#xff08;media&#xff09;是 CSS 中用来针对不同的设备特性&#xff08;如屏幕尺寸、分辨率等&#xff09;应用不同样式的一种技术。通过媒体查询&#xff0c;可以使页面在不同设备上呈现不同的布局&#xff0c;实现响…...

centos系统防火墙SELinux设置指令

SELinux&#xff08;Security-Enhanced Linux&#xff09;的配置可以通过一系列步骤和命令来完成。以下是一些基本的配置SELinux的方法和步骤&#xff1a; 一、查看SELinux状态 首先&#xff0c;你需要查看SELinux的当前状态。可以使用以下命令&#xff1a; getenforce 该命…...

记录如何在RK3588板子上跑通paddle的OCR模型

官网文档地址 rknn_zoo RKNPU2_SDK RKNN Model Zoo 一、PC电脑是Ubuntu22.04系统中完成环境搭建(板子是20.04&#xff09; 安装模型转换环境 ​conda create -n rknn2 python3.10 conda activate rknn2 安装Ubuntu依赖包 su…...

通过AWS Bedrock探索 Claude 的虚拟桌面魔力:让 AI 代替你动手完成任务!

前言 大家好&#xff0c;昨夜Anthropic 发布了更新。现在 Claude 3.5 Sonnet&#xff08;V2&#xff09; 和 Claude 3.5 Haiku&#xff0c;以及名为 computer use 的新功能已经作为公开测试版发布了。 Introducing computer use, a new Claude 3.5 Sonnet, and Claude 3.5 Ha…...

Java面向对象编程高阶(一)

Java面向对象编程高阶&#xff08;一&#xff09; 一、关键字static1、static修饰属性2、静态变量与实例变量的对比3、static修饰方法4、什么时候将属性声明为静态的&#xff1f;5、什么时候将属性声明为静态的&#xff1f;6、代码演示 一、关键字static static用来修饰的结构…...

JavaScript 中 let 和 var 的区别

JavaScript 中 let 和 var 的区别 在 JavaScript 中&#xff0c;let 和 var 都是用来声明变量的关键字&#xff0c;但它们在作用域、提升&#xff08;hoisting&#xff09;和重新赋值方面存在显著差异。理解这些差异对于编写高效和无bug的JavaScript代码至关重要。 作用域 v…...

React第十一章(useReducer)

useReducer useReducer是React提供的一个高级Hook,没有它我们也可以正常开发&#xff0c;但是useReducer可以使我们的代码具有更好的可读性&#xff0c;可维护性。 useReducer 跟 useState 一样的都是帮我们管理组件的状态的&#xff0c;但是呢与useState不同的是 useReducer…...

VUE3实现古典音乐网站源码模板

文章目录 1.设计来源1.1 网站首页页面1.2 古典音乐页面1.3 著名人物页面1.4 古典乐器页面1.5 历史起源页面1.6 登录页面1.7 注册页面 2.效果和源码2.1 动态效果2.2 目录结构 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xc…...

1.nginx安装【Docker】

一、 拉取 最新 nginx 镜像 docker pull nginx二、 拷贝配置文件 2.1 目的 【数据持久化】容器被删除时&#xff0c;它内部的所有数据也会丢失。通过将数据目录挂载到宿主机&#xff0c;可以确保重要数据得到持久化保存 【方便数据管理和调试】通过卷挂载&#xff0c;可以直接…...

Linux -- 共享内存(1)

目录 共享内存 共享内存相关函数 ftok 函数 -- 获取 key 值 什么是 key&#xff1f; 如何生成 key &#xff1f; 参数&#xff1a; 返回值&#xff1a; 封装&#xff1a; shmget 函数 -- 获取 shmid 值 什么是 shmid&#xff1f; shmid 和 key 的区别&#xff1f; …...

冒泡排序和二分查找--go

冒泡排序的逻辑 二分查找的逻辑 func bubbleSort(arr *[5]int){//冒泡排序fmt.Println(*arr)temp : 0for j : len(*arr); j > 0; j-- {for i : 0; i < j-1; i {temp (*arr)[i]if((*arr)[i] > (*arr)[i1]){(*arr)[i] (*arr)[i1](*arr)[i1] temp}}} }func binaryF…...

springboot RedisTemplate支持多个序列化方式

前提纪要&#xff1a;因为业务变动&#xff0c;需要在原先只支持protobuf的前提序列化的前提下&#xff0c;新增正常的序列化读取数据所以在原先的基础上进行优化。文章用于记忆。 话不多说直接上代码 Configuration AutoConfigureAfter(RedisAutoConfiguration.class) Import…...

开源项目-拍卖管理系统

哈喽&#xff0c;大家好&#xff0c;今天主要给大家带来一个开源项目-拍卖管理系统 拍卖管理系统主要有拍卖品管理&#xff0c;我的拍卖&#xff0c;拍卖详情&#xff0c;拍卖品信息修改&#xff0c;发布拍卖品等功能 登录 拍卖商品管理 主要用于查看、竞拍拍卖商品的信息 我…...

Python小游戏14——雷霆战机

首先&#xff0c;你需要确保安装了Pygame库。如果你还没有安装&#xff0c;可以使用pip来安装&#xff1a; bash pip install pygame 代码如下&#xff1a; python import pygame import sys import random # 初始化Pygame pygame.init() # 设置屏幕大小 screen_width 800 scr…...

81页PPT | 企业数字化底座与数字化转型方案

方案内容涵盖了企业数字化转型的议程、集团管理分析类应用建设的现状与问题、数字化建设的目标、预期收益、总体架构、数据产生层、数据交换层、数据存储层、数据应用层、数据管控层等多个方面。方案详细描述了数据从产生、交换、存储到应用的全过程&#xff0c;以及如何通过数…...

R语言笔记(五):Apply函数

文章目录 一、Apply Family二、apply(): rows or columns of a matrix or data frame三、Applying a custom function四、Applying a custom function "on-the-fly"五、Applying a function that takes extra arguments六、Whats the return argument?七、Optimized…...

避免踩坑:Unity中Resources.LoadAll的正确使用姿势(含multiple模式Sprite处理)

Unity资源加载进阶&#xff1a;Resources.LoadAll与Sprite图集高效处理指南 在Unity开发中&#xff0c;资源加载是每个项目都无法绕开的核心环节。特别是当处理包含多张小图的Sprite图集时&#xff0c;很多开发者会陷入性能陷阱和功能误区。本文将深入剖析Resources.LoadAll的正…...

开源电子书工具:如何用鸿蒙系统打造专属个性化阅读空间

开源电子书工具&#xff1a;如何用鸿蒙系统打造专属个性化阅读空间 【免费下载链接】legado-Harmony 开源阅读鸿蒙版仓库 项目地址: https://gitcode.com/gh_mirrors/le/legado-Harmony 你是否曾因阅读应用充斥广告而烦躁&#xff1f;是否渴望完全掌控自己的阅读体验&am…...

保姆级教程:用Docker Compose一键部署带汉化和HTTPS的n8n,并配置反向代理(Nginx)

企业级n8n自动化平台全栈部署实战&#xff1a;从容器编排到安全加固 在数字化转型浪潮中&#xff0c;自动化工作流平台已成为企业降本增效的核心基础设施。n8n作为GitHub上增长最快的开源自动化工具之一&#xff0c;凭借其可视化编排能力和400节点生态&#xff0c;正在重塑企业…...

WavePWM库:嵌入式LED正弦调光算法与实现

1. WavePWM库概述&#xff1a;正弦波形LED调光的底层实现原理与工程应用 WavePWM是一个面向嵌入式LED驱动场景的轻量级波形PWM计算库&#xff0c;其核心价值不在于直接控制硬件引脚&#xff0c;而在于 以确定性数学模型生成高保真度的正弦&#xff08;或类正弦/指数&#xff0…...

避坑指南:Ollama部署DeepSeek-R1时,如何安全地开放API端口给内网其他服务调用?

深度解析&#xff1a;Ollama部署DeepSeek-R1时内网API安全开放实战 当你在一台Linux服务器上成功部署了Ollama和DeepSeek-R1模型后&#xff0c;下一步自然是想让内网中的其他服务也能调用这个强大的AI能力。但直接开放端口就像把家门钥匙插在锁上——方便但危险。本文将带你深入…...

RAG深度解析一:从参数化知识到检索增强的范式重构

【内容定位】深度技术原理【文章日期】2026-03-27【场景引入】进入2026年3月&#xff0c;一场围绕大语言模型“可信性”的讨论在技术社区再度升温。开发者们早已不再争论模型参数量&#xff0c;而是转向一个更实际的问题&#xff1a;如何让动辄千亿参数的大模型&#xff0c;在回…...

Anthropic调整Claude使用限制以缓解高峰时段需求压力

Anthropic公司周三调整了Claude客户的使用限制策略&#xff0c;在高峰需求时段降低服务功率&#xff0c;以平衡用户需求与其服务交付能力。Anthropic技术团队成员Thariq Shihipar在社交媒体上发布消息称&#xff1a;"为了管理Claude日益增长的需求&#xff0c;我们正在调整…...

做了5年GEO优化,我敢说90%的企业都没看懂GEO的真实成本

很多人来问我 GEO 是什么意思&#xff0c;大多是听别人说这是 AI 时代的获客新路子&#xff0c;能比传统推广省好几倍的钱&#xff0c;还能让 AI 优先推荐自己家。但我每次都先不说那些好听的好处&#xff0c;先给大家算清楚&#xff0c;做 GEO 这件事里&#xff0c;那些 90% 的…...

如何快速搭建专业级游戏串流系统:Sunshine完整教程

如何快速搭建专业级游戏串流系统&#xff1a;Sunshine完整教程 【免费下载链接】Sunshine Sunshine: Sunshine是一个自托管的游戏流媒体服务器&#xff0c;支持通过Moonlight在各种设备上进行低延迟的游戏串流。 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine …...

轻量级AI写作工坊:OpenClaw+nanobot内容创作流

轻量级AI写作工坊&#xff1a;OpenClawnanobot内容创作流 1. 为什么需要自动化写作助手 作为一名技术博主兼自媒体运营者&#xff0c;我每天都要面对内容创作的"三重压力"&#xff1a;选题焦虑、写作耗时、发布繁琐。最痛苦的是&#xff0c;当我花两小时写完一篇技…...