第三方登入原理

vbcjnmkk發表於2024-09-01

1、第三方登入原理
第三方登入的原理是藉助OAuth授權來實現,首先使用者先向客戶端提供第三方網站的資料證明自己的身份獲取授權碼,然後客戶端拿著授權碼與授權伺服器建立連線獲得一個Access Token,之後客戶端就可以透過Access Token來與資源伺服器進行互動。

使用OAuth的好處是提供給使用者一個特定的金鑰,使用者持有這個金鑰可以訪問應用中的任何資訊,而不需要向網站提供使用者名稱&密碼,可以實現跨系統共享使用者授權協議。

透過控制使用者持有的金鑰,可以很方便的控制使用者可以訪問的資源,以及控制金鑰的過期時間。

以下是來自維基百科對於OAuth的介紹

開放授權(OAuth)是一個開放標準,允許使用者讓第三方應用訪問該使用者在某一網站上儲存的私密的資源(如照片,影片,聯絡人列表),而無需將使用者名稱和密碼提供給第三方應用。

OAuth允許使用者提供一個令牌,而不是使用者名稱和密碼來訪問他們存放在特定服務提供者的資料。每一個令牌授權一個特定的網站(例如,影片編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相簿中的影片)。這樣,OAuth讓使用者可以授權第三方網站訪問他們儲存在另外服務提供者的某些特定資訊,而非所有內容。

OAuth是OpenID的一個補充,但是完全不同的服務。

互動流程如下:

2、GitHub實現第三方登入
首先需要在github中對應用進行登記,讓Github知道誰在傳送請求。

訪問這個網址,填寫登記表

提交成功之後,GitHub會返回Client ID & Client Secrets ,這是應用的身份識別碼

建立一個SpringBoot工程,pom.xml檔案內容如下:


4.0.0

org.springframework.boot
spring-boot-starter-parent
2.7.17


org.pp
springboot-oauth2-api
0.0.1-SNAPSHOT
springboot-oauth2-api
springboot整合oauth2,實現GitHub第三方登入

<java.version>1.8</java.version>



org.springframework.boot
spring-boot-starter-web


org.springframework.boot
spring-boot-starter-thymeleaf

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>
將ID和金鑰新增到配置檔案application.yml中:

專案埠號

server:
port: 8080

GitHub認證相關引數

github:
client:
id: xxx
secret: xxx
建立一個實體類,用於對映授權成功產生的Token令牌:

import com.fasterxml.jackson.annotation.JsonProperty;
/**
*

  • Token令牌 - 響應引數

  • @author supanpan

  • @date 2023/10/25
    */
    public class AccessTokenResponse {

    @JsonProperty("access_token")
    private String accessToken;

    public String getAccessToken() {
    return accessToken;
    }

    public void setAccessToken(String accessToken) {
    this.accessToken = accessToken;
    }
    }
    OAuthController如下:

**

  • @author supanpan

  • @date 2023/10/25
    */
    @Controller
    public class OAuthController {

    @Value("${github.client.id}")
    private String clientId;

    @Value("${github.client.secret}")
    private String clientSecret;

    @GetMapping("/oauth/redirect")
    public String handleRedirect(@RequestParam("code") String requestToken, Model model) {
    // 使用RestTemplate來傳送HTTP請求
    RestTemplate restTemplate = new RestTemplate();

     // 獲取Token的Url
     String tokenUrl = "https://github.com/login/oauth/access_token" +
             "?client_id=" + clientId +
             "&client_secret=" + clientSecret +
             "&code=" + requestToken;
    
     // 使用restTemplate向GitHub傳送請求,獲取Token
     AccessTokenResponse tokenResponse = restTemplate.postForObject(tokenUrl, null, AccessTokenResponse.class);
    
     // 從響應體中獲取Token資料
     String accessToken = tokenResponse.getAccessToken();
    
     // 攜帶Token向GitHub傳送請求
     String apiUrl = "https://api.github.com/user";
     HttpHeaders headers = new HttpHeaders();
     headers.set("Authorization", "token " + accessToken);
     HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
     ResponseEntity<String> response = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, String.class);
     model.addAttribute("userData", response.getBody());
    
     return "welcome";
    

    }
    }
    SpringBoot啟動器

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootOauth2ApiApplication {

public static void main(String[] args) {
    SpringApplication.run(SpringbootOauth2ApiApplication.class, args);
}

}
還需要編寫兩個html頁面,index.html和welcome.html

index.html

<head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>OAuth2 Demo</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <a id="login">Login with GitHub</a> </body> welcome.html <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Hello</title> </head> <body> <h1>Welcome</h1> <div th:text="${userData}"></div> </body> 啟動專案,瀏覽器訪問localhost:8080,會跳轉到index頁面,點選連結會跳轉到GitHub應用授權頁面

點選跳轉到GitHub授權之後,GitHub會詢問示例程式碼正在請求資料,您是否同意授權。

使用者同意授權, GitHub 就會跳轉到redirect_uri指定的跳轉網址,並且帶上授權碼,跳轉回來的 URL 就是下面的樣子

// code引數就是授權碼
http://localhost:8080/oauth/redirect?code:4ea423f2ec1e04c6376a
如下是服務的響應資料:
//程式碼效果參考:https://www.yopian.com/sitemap/post.html
access token: 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
{
login: 'AtwoodPa',
id: 110728122,
node_id: 'U_kgDOBpmTug',
avatar_url: 'https://avatars.githubusercontent.com/u/110728122?v=4',
gravatar_id: '',
url: 'https://api.github.com/users/AtwoodPa',
html_url: 'https://github.com/AtwoodPa',
followers_url: 'https://api.github.com/users/AtwoodPa/followers',
following_url: 'https://api.github.com/users/AtwoodPa/following{/other_user}',
gists_url: 'https://api.github.com/users/AtwoodPa/gists{/gist_id}',
starred_url: 'https://api.github.com/users/AtwoodPa/starred{/owner}{/repo}',
subscriptions_url: 'https://api.github.com/users/AtwoodPa/subscriptions',
organizations_url: 'https://api.github.com/users/AtwoodPa/orgs',
repos_url: 'https://api.github.com/users/AtwoodPa/repos',
events_url: 'https://api.github.com/users/AtwoodPa/events{/privacy}',
received_events_url: 'https://api.github.com/users/AtwoodPa/received_events',
type: 'User',
site_admin: false,
name: null,
company: null,
blog: '',
location: null,
email: null,
hireable: null,
bio: null,
twitter_username: null,
public_repos: 6,
public_gists: 0,
followers: 0,
following: 3,
created_at: '2022-08-06T13:02:16Z',
updated_at: '2023-09-03T00:15:55Z'
}
authorization code: 4ea423f2ec1e04c6376a
成功執行上述流程,最終展示示例的welcome頁面

到這裡,Spring Boot整合GitHub實現第三方登入的實現就結束了,以此類推其他廠商的第三方登入實現流程也大概是這樣。

相關文章