干货|JustAuth三方账号授权登录免费搭建全流程

三方登录的方式想必大家都很熟悉,基本健全的网页都会整几个入口,比如日常的微信、QQ,金融的支付宝,音视频的抖音、快手,码农领域的Github、Gitee等。

作为功能测试,我们就随机取一个简单的三方授权Gitee来尝试下。由于最近ChhatGPT写代码也是很火,这次的测试主要是chatGPT主导,本人负责辅助实现和测试,不经感叹效率高、能力强!

一、三方登录常规的原理和流程

  1. 用户点击第三方登录按钮,跳转到第三方平台的授权页面。

  2. 用户在第三方平台的授权页面上登录,确认授权。跳转到本地的服务,组装参数配置(response_type/client_id/redirect_uri/state,不同三方参数名可能不同,性质类似),请求三方平台。

  3. 第三方平台验证用户身份,生成授权码或访问令牌(state-对应提交过去的唯一值,code/auth_code,不同三方参数名可能不同,性质类似)。

  4. 用户的浏览器重定向回原网站(根据提交的redirect_uri进行回调),并将授权码或访问令牌传递给原网站。

  5. 原网站使用授权码或访问令牌向第三方平台请求用户信息(用户ID、头像、昵称等)。

  6. 第三方平台返回用户信息给原网站。

  7. 原网站使用用户信息创建或更新本地用户账号,完成用户登录。

了解了基本思路之后,java开发的角度,肯定上来先找轮子(如果有要求要自己实现的话,也可以参考轮子的代码)

这边简单测试,选用了Spring Boot+ JustAuth + Thymeleaf (+ Spring Security 完全没有登录逻辑,可以不加) + IDEA + 内网穿透

以上组件,基本都比较熟悉,简单聊一下 JustAuth

二、关于JustAuth

JustAuth 是一个开源的 Java 三方登录集成工具,它可以帮助开发者快速集成第三方登录功能。

目前支持超过 20 种第三方平台的登录认证,包括但不限于:GitHub、Gitee、微信、QQ、微博、Google、Facebook、Twitter、LinkedIn 等。

使用 JustAuth 可以避免开发者需要针对每个第三方平台编写繁琐的登录认证代码,从而提高开发效率。

从2018年11月开始,一经发布就受到大量的支持,截止目前经过一个个开源人的伟大奉献,到2023年3月10日,JustAuth项目在Github已经有14.5K的star数,足以窥见它的成绩。

下面就借这轮子,一起学习了解下本地测试三方登录的实操流程。前后流程会比较长,请耐心看完。

三、搭建全流程

3.1 前期准备:内网穿透

关于本地开发工具IDEA这就不用多说了,关于使用其他开发工具都是可以的。

由于我们要本地对接公网做联调测试,所以需要内网穿透或者其他自己配置代理的方式都行。

我这边是之前使用购买的花生壳一个6块的域名,并且有送2个内网穿透的配置体验机会,所以就选择这个,这个产品做的也是比较好用。但是HTTP【为响应《网络安全法》,将于2022年6月9日开始,为您提供更安全的外网访问服务,暂停使用HTTP映射】。但是依旧可以配置HTTPS的访问方式,映射本地HTTP的端口都是可以的。

具体配置方式参考:https://service.oray.com/question/8156.html
我参照以上指南,是可以配置好一个公网可访问,代理本地127.0.0.1:8080的接口。

已经具备了以上条件后,继续往下走。

3.2 前期准备:申请一个三方登录授权应用

需要在你需要三方登录对应的平台上去申请三方登录的权限,这边拿Gitee举例。

Gitee官方OAuth的文档:https://gitee.com/api/v5/oauth_doc#/
其中包含:应用名称(随意)、应用描述(随意)、应用主页(随意)、应用回调地址(这是主要的,你自己服务可以回调的地址)、权限(按需选择)
填写好之后直接提交配置,就可以获取接口所需的client-id和client-secret。

在这里插入图片描述

  1. 在 修改资料 -> 第三方应用,创建要接入码云的应用。
  2. 填写应用相关信息,勾选应用所需要的权限。其中: 回调地址是用户授权后,码云回调到应用,并且回传授权码的地址。正常三方登录,勾选用户权限+个人邮箱信息基本就够了。
  3. 创建成功后,会生成 Cliend ID 和 Client Secret。他们将会在上述OAuth2 认证基本流程用到。
    在这里插入图片描述

3.3 开发指南:引入组件

确定具备一个基本的java\maven的项目,在pom.xml中引入

  • Spring Boot
  • JustAuth
  • Thymeleaf
  • Spring Security 不需要其他认证,可以不加

这边为了测试偷懒,引入了【justauth-spring-boot-starter】,以下是测试的POM

<dependencies>
        <dependency>
            <groupId>com.xkcoding.justauth</groupId>
            <artifactId>justauth-spring-boot-starter</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 排除 Spring Boot 默认的日志依赖 -->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <!-- Thymeleaf 模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- Spring Security 安全框架 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

3.4 开发指南:构建一个基本的授权登录框架

以下含非必须环节,不需要可自动过滤。

SpringSecurity身份验证,内置一个账号密码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/home").authenticated()
                .antMatchers("/oauth/**").permitAll()
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/home")
                .failureUrl("/login?error=true")
                .and()
                .logout()
                .logoutSuccessUrl("/login");
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("{noop}password").roles("USER")
                .and()
                .withUser("admin").password("{noop}123456").roles("ADMIN");
    }
}

简单配备一个日志输出:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

简单配备一个登录页:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<h1>Login</h1>
<div th:if="${param.error}">
    <p>Invalid username and password.</p>
</div>
<div th:if="${param.logout}">
    <p>You have been logged out.</p>
</div>
<form th:action="@{/login}" method="post">
    <div>
        <label for="username">Username:</label>
        <input type="text" id="username" name="username"/>
    </div>
    <div>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password"/>
    </div>
    <div>
        <button type="submit">Login</button>
    </div>
</form>
<div>
    <a th:href="@{/oauth/login/gitee}">
        <img src="https://huashuimoyu.com/image/thirdlogo/gitee.png" width="40px" height="40px"/>
    </a>
</div>
</body>
</html>

简单配备一个登录跳转逻辑:

@Controller
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "home";
    }

    @GetMapping("/home")
    public String home2() {
        return "home";
    }

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @PostMapping("/login")
    public String loginWithUsenamePassword(String username,String password){
        System.out.println(username);
        System.out.println(password);
       return "success";
    }
}

到这边,使用Springboot+SpringSecurity 依靠登录框进行账号密码登录的基本流程可以通了,此外依赖花生壳一个映射的配置,使用公网一个https的访问路径就可以访问到这个登录页了。
在这里插入图片描述

3.5 JustAuth+Gitee的三方登录

下面接入JustAuth补充Gitee的三方登录
前面依赖已经引入了,使用自动装配,只要在application的配置文件配置下、书写确定的跳转和回调接口即可

justauth:
  enabled: true
  type:
    QQ:
    GITEE:
      client-id: 56ba1xxxxxx3c7d
      client-secret: 90c7xxxxxx129a97
      redirect-uri: https://exxxxxxxxn/oauth/gitee/callback #就你本地自己提供出去的登录跳转的API,注意是公网可访问的

使用JustAuth简单实现一个调用和回调:

刚才在登录页就简单用一张图片链接触发一个三方登录请求。

<div>
    <a th:href="@{/oauth/login/gitee}">
        <img src="https://huashuimoyu.com/image/thirdlogo/gitee.png" width="40px" height="40px"/>
    </a>
</div>

点击图片后,跳转到后端接口,后端接口组装认证参数,提交到Gitee接口。

    @GetMapping("/login/{type}")
    public void login(@PathVariable String type, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = factory.get(type);
        response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
    }

请求Gitee,跳转到Gitee的授权登录页,选择想要授予的权限,点击确定。
在这里插入图片描述

确定后,Gitee就会将网址跳转到我们提交的redirect_url上,我们做出正确响应即可。

    @RequestMapping("/{type}/callback")
    public AuthResponse login(@PathVariable String type, AuthCallback callback) {
        AuthRequest authRequest = factory.get(type);
        AuthResponse response = authRequest.login(callback);
        System.out.println("【response】= {}"+JSON.toJSONString(response));
        return response;
    }

接口获取授权信息:
在这里插入图片描述
这个时候,我们的页面可以回到一个授权成功,正在登录页。我们可以在这个时候拿到Gitee用户的一些昵称、头像、uid这些信息,记录在自己网站中,后期可以直接认证。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
史上最的整合第三方登录的工具,目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软和今日头条等第三方平台的授权登录。 Login, so easy!JustAuth,如你所见,它仅仅是一个第三方授权登录的工具类库,它可以让我们脱离繁琐的第三方登录SDK,让登录变得So easy!项目开源地址:gitee | github特点废话不多说,就俩字::已集成十多家第三方平台(国内外常用的基本都已包含),后续依然还有扩展计划!简:API就是奔着最简单去设计的(见后面快速开始),尽量让您用起来没有障碍感!快速开始引入依赖     me.zhyd.oauth     JustAuth     1.8.0 调用api// 创建授权request AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()         .clientId("clientId")         .clientSecret("clientSecret")         .redirectUri("redirectUri")         .state("state")         .build()); // 生成授权页面 authRequest.authorize(); // 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的参数 authRequest.login(callback);注:1.8.0版本后,增加了state参数校验,用于防止CSRF。强烈建议,保证单次流程内state的唯一性,且每个state只可用一次。配套Demo:JustAuth-demo具体的例子可以参考:实现Gitee授权登录实现Github授权登录API列表平台API类 SDKAuthGiteeRequest参考文档AuthGithubRequest参考文档AuthWeiboRequest参考文档AuthDingTalkRequest参考文档AuthBaiduRequest参考文档AuthCodingRequest参考文档AuthTencentCloudRequest参考文档AuthOschinaRequest参考文档AuthAlipayRequest参考文档AuthQqRequest参考文档AuthWeChatRequest参考文档AuthTaobaoRequest参考文档AuthGoogleRequest参考文档AuthFacebookRequest参考文档AuthDouyinRequest参考文档AuthLinkedinRequest参考文档AuthMicrosoftRequest参考文档AuthMiRequest参考文档AuthToutiaoRequest参考文档AuthCsdnRequest无请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经下线。如果以前申请过的应用,可以继续使用,但是不再支持申请新的应用。so, 本项目中的CSDN登录只能针对少部分用户使用了后续开发计划参考:[开发计划] 待扩展的第三方平台另外,期待您和我一起完善这个项目!贡献代码fork本项目到自己的repo把fork过去的项目也就是你仓库中的项目clone到你的本地修改代码commit后push到自己的库发起PR(pull request) 请求等待作者合并致谢在项目立项初期,也对当前开源圈的一些相同类型的项目作过调研,同时本项目也参考过这些项目,再次感谢开源圈内的朋友。YurunOAuthLogin: PHP 第三方登录授权 SDK阿里妈妈MUX倾力打造的矢量图标库-iconfont: 本文档中的图标大部分取自该平台
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c_zyer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值