Java实现Google授权登录,OAuth 2.0登录

首先创建OAuth 2.0 客户端 ID
在这里插入图片描述
配置url,必须是https的,同时复制好客户端id 和密钥

在这里插入图片描述
配置回调url
在这里插入图片描述

    /**
     * Google授权登录跳转。但是会重定向,建议前端跳转
     *
     * 前端js
     * // 构建 Google 授权 URL
     * const authParams = new URLSearchParams({
     *   response_type: 'code', //固定
     *   client_id: 'YOUR_CLIENT_ID', // 请将 YOUR_CLIENT_ID 替换为实际的客户端 ID
     *   scope: 'openid email profile',  //固定
     *   redirect_uri: 'YOUR_REDIRECT_URI', // 在Google配置的回调url
     * });
     *
     * const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?${authParams}`;
     *
     通过Java接口跳转Google登录页面,会重定向,建议前端跳转
     * @param response
     * @return
     * @throws IOException
     */
    @GetMapping("/google-login")
    @NoAuth
    public CommonResult<String> googleLogin(HttpServletResponse response) throws IOException {
        HttpTransport httpTransport = new NetHttpTransport();
        JsonFactory jsonFactory = GsonFactory.getDefaultInstance();

        // 设置 OAuth 2.0 授权码流对象
        AuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, SCOPES)
                .setAccessType("offline")
                .setApprovalPrompt("force") // 可选,强制用户重新授权
                .build();

        // 生成用户授权的 URL
        AuthorizationCodeRequestUrl authorizationUrl = flow.newAuthorizationUrl()
                .setRedirectUri(REDIRECT_URI);

        // 重定向用户到授权 URL
        response.sendRedirect(authorizationUrl.build());
        return new CommonResult("success");
    }

回调接口

 @GetMapping("/google-callback")
    @NoAuth //不需要登录
    public ResponseEntity<String> googleCallback(@RequestParam("code") String authorizationCode) throws IOException {
        System.out.println("google-callback code = "+authorizationCode);

        // 创建 Google 授权码流对象
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                new NetHttpTransport(),
                JacksonFactory.getDefaultInstance(),
                CLIENT_ID,
                CLIENT_SECRET,
                Arrays.asList("openid", "email", "profile"))
                .setAccessType("offline")
                .build();

        // 交换授权码为访问令牌
        TokenResponse tokenResponse = flow.newTokenRequest(authorizationCode)
                .setRedirectUri(REDIRECT_URI)
                .execute();
        String accessToken = tokenResponse.getAccessToken();

//        System.out.println("google accessToken: "+accessToken);

        String userInfo = getUserInfo(accessToken);
//        System.out.println("userInfo: "+userInfo);
        /** 格式
         * {
         *   "iss": "https://accounts.google.com",
         *   "sub": "123456789012345678901",  表示用户的唯一标识符,通常是用户的Google ID。
         *   "aud": "your-client-id",
         *   "email": "user@example.com",
         *   "email_verified": true,
         *   "exp": 1627889766,
         *   "iat": 1627886166
         * }
         */
        JSONObject jsonObject = JSONObject.parseObject(userInfo);
        String email =  jsonObject.getString("email") ;
        //登录逻辑
        JSONObject userJson = loginByEmail(email);
        String redirectUrl = "https://funflixvideo.com/#/?userId="+userJson.getString("userId")+"&sessionId="+userJson.getString("sessionId");
        // 重定向到 H5 页面,并带上 session ID
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(URI.create(redirectUrl));
        return new ResponseEntity<>(headers, HttpStatus.FOUND);
    }
    
    //获取用户信息
 public  String getUserInfo(String accessToken) {

        String url = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + accessToken;
        try {
            return HttpClient4Utils.httpGet(url, null, "utf-8", 30);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java linq多字段排序时间比较

public static void main(String[] args) {//100万条数据List<CrmInvestSaleUserCount> waitAssignUserList new ArrayList<>();for (int i 0; i < 1000000; i) {waitAssignUserList.add(new CrmInvestSaleUserCount().setSales_username("test" i…

单元测试之 - Spring框架提供的单元/集成测试注解

Spring框架提供了很多注解来辅助完成单元测试和集成测试(备注&#xff1a;这里的集成测试指容器内部的集成测试&#xff0c;非系统间的集成测试)&#xff0c;先看看Spring框架提供了哪些注解以及对应的作用。RunWith(SpringRunner.class) / ExtendWith(SpringExtension.class)&…

KepwareEX配置API REST接口

服务端Kepware设置 API允许连接设置 创建通道 请求地址(POST)&#xff1a; https://<主机名_或_ip>:<端口>/config/v1/project/channels 以下示例使用postman工具访问API创建了一个名为Channel1 的通道&#xff0c;其使用在本地主机运行的服务器中的Simulator …

VSCode如何在行内显示变量值

背景 在调试时&#xff0c;我们希望能够直接在代码行显示变量的值&#xff0c;而不是总是去侧边栏查看&#xff0c;如下这种&#xff0c;y12直接显示在代码行。那么VSCode中如何做呢 设置 VSCode提供了“inline values”设置&#xff0c;但为了速度&#xff0c;默认并没有开…

Python3 网络爬虫开发实战

第二章 基本库的使用 urlib的使用 比较好用的是parse模块来进行URL的各种处理&#xff0c; requests的使用 requests库也可以session维持&#xff0c;srequests.Session(),s.get(url‘…’) 有些网站没有设置好HTTPS证书&#xff0c;导致出现不是私密连接的错误&#xff0c…

Ubuntu开机自启服务systemd.service配置教程(Ubuntu服务)(Linux服务)upstart

文章目录 为什么要将程序配置成服务&#xff1f;1. 自动启动2. 后台运行3. 定时重启4. 简化管理5. 整合系统 版本支持1. Ubuntu 14.04及更早版本&#xff1a;使用upstart作为默认的init系统/etc/rc.local旧版本新版本 2. Ubuntu 15.04到16.04版本&#xff1a;默认使用systemd作…

6.s081/6.1810(Fall 2022)Lab5: Copy-on-Write Fork for xv6

前言 本来往年这里还有个Lazy Allocation的&#xff0c;今年不知道为啥直接给跳过去了。. 其他篇章 环境搭建 Lab1: Utilities Lab2: System calls Lab3: Page tables Lab4: Traps Lab5: Copy-on-Write Fork for xv6 参考链接 官网链接 xv6手册链接&#xff0c;这个挺重要…

【云原生】Docker-compose中所有模块学习

compose模块 模板文件是使用 Compose 的核心&#xff0c;涉及到的指令关键字也比较多。但大家不用担心&#xff0c;这里面大部分指令跟 docker run 相关参数的含义都是类似的。 默认的模板文件名称为 docker-compose.yml&#xff0c;格式为 YAML 格式。 version: "3&quo…

【从零学习python 】02. 开发工具介绍

文章目录 编写Python代码一、常见的代码编辑工具二、运行Python程序三、Pycharm的下载和安装PyCharm的主要功能区域进阶案例 编写Python代码 根据我们之前介绍的知识&#xff0c;我们知道&#xff0c;所谓代码其实就是将一段普通文本按照一定的规范编写&#xff0c;然后交给电…

人工智能的缺陷

首先从应用层面理解什么是人工智能&#xff0c;目前人工智能主流应用面包括&#xff1a;自然语言处理领域&#xff0c;代表为chatgpt&#xff0c;我们能用其进行日常交流&#xff0c;问题答疑&#xff0c;论文书写等。计算机视觉领域&#xff0c;代表为人脸识别&#xff0c;现在…

百度UEditor编辑器如何关闭抓取远程图片功能

百度UEditor编辑器如何关闭抓取远程图片功能 这个坑娘的功能&#xff0c;开始时居然不知道如何触发&#xff0c;以为有个按钮&#xff0c;点击一下触发&#xff0c;翻阅了文档&#xff0c;没有发现&#xff0c;然后再网络上看到原来是复制粘贴非白名单内的图片到编辑框时触发&a…

centos7 yum源安装出错及更新问题

如下 首先&#xff0c;在搜索jdk时报错如下&#xff1a; 解决办法 1、进入 yum的repo目录 cd /etc/yum.repos.d/2、修改所有的CentOS文件内容 sed -i s/mirrorlist/#mirrorlist/g /etc/yum.repos.d/CentOS-*sed -i s|#baseurlhttp://mirror.centos.org|baseurlhttp://vau…

Rust 编程小技巧摘选(7)

Rust 编程小技巧(7) 1. 结构体 Display trait 结构体的两种形式&#xff0c;对应的成员取法不同&#xff1b; 前者用 self.成员变量名 self.x, self.y&#xff1b;后者用 self.成员索引号 self.0, self.1, self.2, ...... use std::fmt::Display; use std::fmt::Result; us…

如何从 Android 设备恢复已删除的文件?

从 Android 设备恢复已删除的文件很简单&#xff0c;但您需要了解内部恢复和SD 卡恢复之间的区别。 目前销售的大多数 Android 设备都配备了 SD 卡插槽&#xff08;通常为 microSD&#xff09;&#xff0c;可以轻松添加额外的存储空间。该存储空间可用于存储照片、视频、文档&a…

配置Hive远程服务详细步骤

HiveServer2支持多客户端的并发和认证&#xff0c;为开放API客户端如JDBC、ODBC提供了更好的支持。 &#xff08;1&#xff09;修改hive-site.xml&#xff0c;在文件中添加以下内容&#xff1a; <property><name>hive.metastore.event.db.notification.api.auth&l…

ArcGIS Pro简介下载安装地址

ArcGIS Pro简介 ArcGIS Pro是一款功能强大的地理信息系统&#xff08;GIS&#xff09;软件&#xff0c;由Esri开发。它为用户提供了一种直观、灵活且高效的方式来处理、分析和可视化地理数据。ArcGIS Pro具有现代化的用户界面和工作流程&#xff0c;使用户能够更好地利用地理信…

【Linux】节点之间配置免密登录

文章目录 1、实现2、原理3、SSH的理解 1、实现 先写实现&#xff0c;解决问题后有兴趣的自己看后面的原理。 以实现节点A&#xff08;主&#xff09;免密登录到节点B&#xff08;从&#xff09;为例&#xff1a;&#xff08;注意例子里节点B被登录&#xff09; 步骤一&#xf…

L2CS-Net: 3D gaze estimation

L2CS-Net: Fine-Grained Gaze Estimation in Unconstrained Environments论文解析 摘要1. 简介2. Related Work3. METHOD3.1 Proposed loss function3.2 L2CS-Net 结构3.3 数据集3.4 评价指标 4. 实验4.1 实验结果 论文地址&#xff1a;L2CS-Net: Fine-Grained Gaze Estimation…

Mysql主从复制-主库/从库

介绍 mysql的主从复制是一个异步的复制过程&#xff0c;底层是基于Mysql数据库自带的二进制日志功能&#xff0c;就是一台或多台数据库&#xff08;slave,从库&#xff09;从另一台MYSQL数据库&#xff08;master,主库&#xff09;进行日志的复制然后再解析并应用到自己&#…

IO进程线程第五天(8.2)进程函数+XMind(守护进程(幽灵进程),输出一个时钟,终端输入quit时退出时钟)

1.守护进程&#xff08;幽灵进程&#xff09; #include<stdio.h> #include<head.h> int main(int argc, const char *argv[]) {pid_t cpid fork();if(0cpid){ //创建新的会话pid_t sidsetsid();printf("sid%d\n",sid);//修改运行目录为不可卸载的文件…