Spring Boot 快速集成第三方登錄功能

原文鏈接:https://xkcoding.com/2019/05/22/spring-boot-login-with-oauth.html

Spring Boot 快速集成第三方登錄功能

前言

 

此 demo 主要演示 Spring Boot 項目如何使用 史上最全的第三方登錄工具 - JustAuth 實現第三方登錄,包括 QQ 登錄、GitHub 登錄、微信登錄、谷歌登錄、微軟登錄、小米登錄、企業微信登錄。

通過 justauth-spring-boot-starter 快速集成,好嗨喲~

JustAuth,如你所見,它僅僅是一個第三方授權登錄工具類庫,它可以讓我們脫離繁瑣的第三方登錄 SDK,讓登錄變得So easy!

  1. :已集成十多家第三方平臺(國內外常用的基本都已包含),後續依然還有擴展計劃!
  2. :API 就是奔着最簡單去設計的(見後面快速開始),儘量讓您用起來沒有障礙感!

PS: 本人十分幸運的參與到了這個 SDK 的開發,主要開發了 QQ 登錄、微信登錄、小米登錄、微軟登錄、谷歌登錄這 5 個第三方登錄,以及一些 BUG 的修復工作。再次感謝 @母狼 開源這個又好用又全面的第三方登錄 SDK。

如果技術選型是 JFinal 的,請查看此 demo

https://github.com/xkcoding/jfinal-justauth-demo

如果技術選型是 ActFramework 的,請查看此 demo

https://github.com/xkcoding/act-justauth-demo


1. 環境準備

1.1. 公網服務器準備

首先準備一臺有公網 IP 的服務器,可以選用阿里雲或者騰訊雲,如果選用的是阿里雲的,可以使用我的優惠鏈接購買。

1.2. 內網穿透 frp 搭建

frp 安裝程序:https://github.com/fatedier/frp/releases

1.2.1. frp 服務端搭建

服務端搭建在上一步準備的公網服務器上,因爲服務器是 centos7 x64 的系統,因此,這裏下載安裝包版本爲 linux_amd64 的 frp_0.27.0_linux_amd64.tar.gz 。

  1. 下載安裝包

    複製
    1
    
    $ wget https://github.com/fatedier/frp/releases/download/v0.27.0/frp_0.27.0_linux_amd64.tar.gz
    
  2. 解壓安裝包

    複製
    1
    
    $ tar -zxvf frp_0.27.0_linux_amd64.tar.gz
    
  3. 修改配置文件

    複製
    1
    2
    3
    4
    5
    6
    
    $ cd frp_0.27.0_linux_amd64
    $ vim frps.ini
    
    [common]                                                                                                                  
    bind_port = 7100                                                                                                          
    vhost_http_port = 7200
    
  4. 啓動 frp 服務端

    複製
    1
    2
    3
    4
    
    $ ./frps -c frps.ini
    2019/06/15 16:42:02 [I] [service.go:139] frps tcp listen on 0.0.0.0:7100
    2019/06/15 16:42:02 [I] [service.go:181] http service listen on 0.0.0.0:7200
    2019/06/15 16:42:02 [I] [root.go:204] Start frps success
    

1.2.2. frp 客戶端搭建

客戶端搭建在本地的 Mac 上,因此下載安裝包版本爲 darwin_amd64 的 frp_0.27.0_darwin_amd64.tar.gz 。

  1. 下載安裝包

    複製
    1
    
    $ wget https://github.com/fatedier/frp/releases/download/v0.27.0/frp_0.27.0_darwin_amd64.tar.gz
    
  2. 解壓安裝包

    複製
    1
    
    $ tar -zxvf frp_0.27.0_darwin_amd64.tar.gz
    
  3. 修改配置文件,配置服務端 ip 端口及監聽的域名信息

    複製
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    $ cd frp_0.27.0_darwin_amd64
    $ vim frpc.ini
    
    [common]
    server_addr = 120.92.169.103
    server_port = 7100
    
    [web]
    type = http
    local_port = 8080
    custom_domains = oauth.xkcoding.com
    
  4. 啓動 frp 客戶端

    複製
    1
    2
    3
    4
    
    $ ./frpc -c frpc.ini
    2019/06/15 16:48:52 [I] [service.go:221] login to server success, get run id [8bb83bae5c58afe6], server udp port [0]
    2019/06/15 16:48:52 [I] [proxy_manager.go:137] [8bb83bae5c58afe6] proxy added: [web]
    2019/06/15 16:48:52 [I] [control.go:144] [web] start proxy success
    

1.3. 配置域名解析

前往阿里雲 DNS 解析,將域名解析到我們的公網服務器上,比如我的就是將 oauth.xkcoding.com -> 120.92.169.103

image-20190615165843639

1.4. nginx 代理

nginx 的搭建就不在此贅述了,只說配置

複製

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
    listen       80;
    server_name  oauth.xkcoding.com;         
                                                                        
    location / {
        proxy_pass http://127.0.0.1:7200;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header   X-Real-IP        $remote_addr;                                                                 
        proxy_buffering off;                                                                                              
        sendfile off;                                                                                                     
        proxy_max_temp_file_size 0;                                                                                       
        client_max_body_size       10m;                                                                                   
        client_body_buffer_size    128k;                                                                                  
        proxy_connect_timeout      90;                                                                                    
        proxy_send_timeout         90;                                                                                    
        proxy_read_timeout         90;                                                                                    
        proxy_temp_file_write_size 64k;                                                                                   
        proxy_http_version 1.1;                                                                                           
        proxy_request_buffering off; 
    }
}

測試配置文件是否有問題

複製

1
2
3
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

重新加載配置文件,使其生效

複製

1
$ nginx -s reload

現在當我們在瀏覽器輸入 oauth.xkcoding.com 的時候,網絡流量其實會經歷以下幾個步驟:

  1. 通過之前配的 DNS 域名解析會訪問到我們的公網服務器 120.92.169.103 的 80 端口
  2. 再經過 nginx,代理到本地的 7200 端口
  3. 再經過 frp 穿透到我們的 Mac 電腦的 8080 端口
  4. 此時 8080 就是我們的應用程序端口

1.5. 第三方平臺申請

1.5.1. QQ 互聯平臺申請

  1. 前往 https://connect.qq.com/

  2. 申請開發者

  3. 應用管理 -> 添加網站應用,等待審覈通過即可

    image-20190617144655429

1.5.2. GitHub 平臺申請

  1. 前往 https://github.com/settings/developers

  2. 點擊 New OAuth App 按鈕創建應用

    image-20190617145839851

1.5.3 微信開放平臺申請

這裏微信開放平臺需要用企業的,個人沒有資質,所以我在某寶租了一個月的資質,需要的可以 戳我租賃

聲明:本人與該店鋪無利益相關,純屬個人覺得好用做分享

該店鋪有兩種方式:

  1. 店鋪支持幫你過企業資質,這裏就用你自己的開放平臺號就好了
  2. 臨時使用可以問店家租一個月進行開發,這裏租了之後,店家會把 AppID 和 AppSecret 的信息發給你,你提供回調域就好了

因此這裏我就貼出一張授權回調的地址作參考。

image-20190617153552218

1.5.4. 谷歌開放平臺申請

  1. 前往 https://console.developers.google.com/projectcreate 創建項目

  2. 前往 https://console.developers.google.com/apis/credentials ,在第一步創建的項目下,添加應用

    image-20190617151119584

    image-20190617150903039

1.5.5. 微軟開放平臺申請

  1. 前往 https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade 註冊應用

  2. 在註冊應用的時候就需要填寫回調地址,當然後期也可以重新修改

    image-20190617152529449

  3. client id 在這裏

    image-20190617152805581

  4. client secret 需要自己在這裏生成

    image-20190617152711938

1.5.6. 小米開放平臺申請

  1. 申請小米開發者,審覈通過

  2. 前往 https://dev.mi.com/passport/oauth2/applist 添加 oauth 應用,選擇 創建網頁應用

  3. 填寫基本信息之後,進入應用信息頁面填寫 回調地址

    image-20190617151502414

  4. 應用審覈通過之後,可以在應用信息頁面的 應用詳情 查看到 AppKey 和 AppSecret,吐槽下,小米應用的審覈速度特別慢,需要耐心等待。。。。

    image-20190617151624603

1.5.7. 企業微信平臺申請

參考:https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html


2. 主要代碼

代碼地址:https://github.com/xkcoding/spring-boot-demo/tree/master/spring-boot-demo-social

2.1. pom.xml

複製

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <artifactId>spring-boot-demo-social</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>spring-boot-demo-social</name>
  <description>Demo project for Spring Boot</description>

  <parent>
    <groupId>com.xkcoding</groupId>
    <artifactId>spring-boot-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <justauth-spring-boot.version>1.0.0</justauth-spring-boot.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <!-- 對象池,使用redis時必須引入 -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
    </dependency>

    <!-- oauth工具類 -->
    <dependency>
      <groupId>com.xkcoding</groupId>
      <artifactId>justauth-spring-boot-starter</artifactId>
      <version>${justauth-spring-boot.version}</version>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>

    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
    </dependency>

    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
    </dependency>
  </dependencies>

  <build>
    <finalName>spring-boot-demo-social</finalName>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

2.2. application.yml

複製

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
server:
  port: 8080
  servlet:
    context-path: /demo

spring:
  redis:
    host: localhost
    # 連接超時時間(記得添加單位,Duration)
    timeout: 10000ms
    # Redis默認情況下有16個分片,這裏配置具體使用的分片
    # database: 0
    lettuce:
      pool:
        # 連接池最大連接數(使用負值表示沒有限制) 默認 8
        max-active: 8
        # 連接池最大阻塞等待時間(使用負值表示沒有限制) 默認 -1
        max-wait: -1ms
        # 連接池中的最大空閒連接 默認 8
        max-idle: 8
        # 連接池中的最小空閒連接 默認 0
        min-idle: 0
  cache:
    # 一般來說是不用配置的,Spring Cache 會根據依賴的包自行裝配
    type: redis

justauth:
  enabled: true
  type:
    qq:
      client-id: 10******85
      client-secret: 1f7d************************d629e
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/qq/callback
    github:
      client-id: 2d25******d5f01086
      client-secret: 5a2919b************************d7871306d1
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/github/callback
    wechat:
      client-id: wxdcb******4ff4
      client-secret: b4e9dc************************a08ed6d
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat/callback
    google:
      client-id: 716******17-6db******vh******ttj320i******userco******t.com
      client-secret: 9IBorn************7-E
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/google/callback
    microsoft:
      client-id: 7bdce8******************e194ad76c1b
      client-secret: Iu0zZ4************************tl9PWan_.
      redirect-uri: https://oauth.xkcoding.com/demo/oauth/microsoft/callback
    mi:
      client-id: 288************2994
      client-secret: nFeTt89************************==
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/mi/callback
    wechat_enterprise:
      client-id: ww58******f3************fbc
      client-secret: 8G6PCr00j************************rgk************AyzaPc78
      redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat_enterprise/callback
      agent-id: 1******2

2.3. OauthController.java

複製

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**
 * <p>
 * 第三方登錄 Controller
 * </p>
 *
 * @package: com.xkcoding.oauth.controller
 * @description: 第三方登錄 Controller
 * @author: yangkai.shen
 * @date: Created in 2019-05-17 10:07
 * @copyright: Copyright (c) 2019
 * @version: V1.0
 * @modified: yangkai.shen
 */
@Slf4j
@RestController
@RequestMapping("/oauth")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class OauthController {
    private final AuthRequestFactory factory;

    /**
     * 登錄類型
     */
    @GetMapping
    public Map<String, String> loginType() {
        List<String> oauthList = factory.oauthList();
        return oauthList.stream().collect(Collectors.toMap(oauth -> oauth.toLowerCase() + "登錄", oauth -> "http://oauth.xkcoding.com/demo/oauth/login/" + oauth.toLowerCase()));
    }

    /**
     * 登錄
     *
     * @param oauthType 第三方登錄類型
     * @param response  response
     * @throws IOException
     */
    @RequestMapping("/login/{oauthType}")
    public void renderAuth(@PathVariable String oauthType, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = factory.get(getAuthSource(oauthType));
        response.sendRedirect(authRequest.authorize(oauthType + "::" + AuthStateUtils.createState()));
    }

    /**
     * 登錄成功後的回調
     *
     * @param oauthType 第三方登錄類型
     * @param callback  攜帶返回的信息
     * @return 登錄成功後的信息
     */
    @RequestMapping("/{oauthType}/callback")
    public AuthResponse login(@PathVariable String oauthType, AuthCallback callback) {
        AuthRequest authRequest = factory.get(getAuthSource(oauthType));
        AuthResponse response = authRequest.login(callback);
        log.info("【response】= {}", JSONUtil.toJsonStr(response));
        return response;
    }

    private AuthSource getAuthSource(String type) {
        if (StrUtil.isNotBlank(type)) {
            return AuthSource.valueOf(type.toUpperCase());
        } else {
            throw new RuntimeException("不支持的類型");
        }
    }
}

2.4. 如果想要自定義 state 緩存

請看👉這裏


3. 運行方式

打開瀏覽器,輸入 http://oauth.xkcoding.com/demo/oauth ,點擊各個登錄方式自行測試。

Google 登錄,有可能因爲祖國的強大導致測試失敗,自行解決~ :kissing_smiling_eyes:

image-20190809161032422


參考

  1. JustAuth 項目地址:https://github.com/justauth/JustAuth
  2. justauth-spring-boot-starter 地址:https://github.com/justauth/justauth-spring-boot-starter
  3. frp 內網穿透項目地址:https://github.com/fatedier/frp
  4. frp 內網穿透官方中文文檔:https://github.com/fatedier/frp/blob/master/README_zh.md
  5. Frp 實現內網穿透:https://zhuanlan.zhihu.com/p/45445979
  6. QQ 互聯文檔:http://wiki.connect.qq.com/%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C_oauth2-0
  7. 微信開放平臺文檔:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN
  8. GitHub 第三方登錄文檔:https://developer.github.com/apps/building-oauth-apps/
  9. 谷歌 Oauth2 文檔:https://developers.google.com/identity/protocols/OpenIDConnect
  10. 微軟 Oauth2 文檔:https://docs.microsoft.com/zh-cn/graph/auth-v2-user
  11. 小米開放平臺賬號服務文檔:https://dev.mi.com/console/doc/detail?pId=707

------------- 本文結束  感謝您的閱讀 -------------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章