OAuth实战

利用GitHub的OAuth授权实战

身份注册

要想得到一个网站的OAuth授权,必须要到它的网站进行身份注册,拿到应用的身份识别码 ClientIDClientSecret

传送门https://github.com/settings/applications/new

有几个必填项。

  • Application name:我们的应用名;

  • Homepage URL:应用主页链接;

  • Authorization callback URL:这个是github 回调我们项目的地址,用来获取授权码和令牌

提交后会看到就可以看到客户端ClientID 和客户端密匙ClientSecret,到这我们的准备工作就完事了

授权开发

第1步:客户端向资源拥有者发送授权请求,一般资源拥有者的资源会存放在资源服务器

我们在这里新建一个html界面,用来模拟登录请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Page</title>
<script>
function login() {
alert("登录")
window.location.href = 'https://github.com/login/oauth/authorize?client_id=a98e2191927c000f4eac&redirect_uri=http://localhost:8080/authorize/redirect'
}
</script>
</head>
<body>
<h1>Welcome to the Login Page</h1>
<button onclick="login()">Login</button>
</body>
</html>
第2步:客户端会收到资源服务器的授权许可
当我们点击登录按钮,会提示让我们授权,同意授权后会重定向到authorize/redirect,并携带授权码code;如果之前已经同意过,会跳过这一步直接回调第3步:客户端拿到许可之后,再向授权服务器发送一次验证,给客户端颁发一个Access Token访问令牌

授权后紧接着就要回调 adminflow 网站接口,拿到授权码以后拼装获取令牌 access_token的请求链接,这时会用到客户端密匙client_secret

第4步:客户端拿到令牌之后,交给资源服务器
**第5步:**资源服务器会将获取到的令牌传给认证服务器验证令牌的有效性。
**第6步:**资源服务器验证令牌通过之后,就会返回一个受保护的资源。
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
package org.pt.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;


@RestController
public class UserController {
@Value("${github.clientId}")
private String clientId;

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


@GetMapping("/authorize/redirect")
public String githubCallback(@RequestParam("code") String code) {
String tokenUrl = "https://github.com/login/oauth/access_token";
String requestBody = "client_id=" + clientId + "&client_secret=" + clientSecret + "&code=" + code;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(tokenUrl, HttpMethod.POST, requestEntity, String.class);
if (response.getStatusCode() == HttpStatus.OK) {
// Extract access token from response body
String[] parts = response.getBody().split("&");
for (String part : parts) {
System.out.println(part);
if (part.startsWith("access_token")) {
String[] split = part.split("=");
return split[1];
}
}
}
return null;
}

}

我们这里拿到许可之后,向服务器发送一次验证,获取access toke,有了令牌以后开始获取用户信息,在 API 中要带上access_token

利用postman发送请求,请求地址为https://api.github.com/user

加入Authorization,Type为Beare 值为返回的access token

请求结果

返回的用户信息是 JSON 数据格式,如果想把数据传递给前端,可以通过 url 重定向到前端页面,将数据以参数的方式传递

源代码https://github.com/Breeze1203/JavaAdvanced/tree/main/springboot-demo/spring-boot-oAuth2