OAuth 2.0
授权模式
授权码
三方应用先申请一个授权码,然后通过该授权码获得令牌。
假设 A 网站要使用B网站的用户信息。
A 网站要先申请 client_id
和 client_secret
第一步,A提供一个连接,用户点击后跳转到B网站,授权用户给数据给A网站使用。
第一步 用户点击B网站登录跳转到B网站
A->B 链接
一个位于 A 网站上的链接 例如 B网站登录
https://b.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read
假设 CALLBACK_URL = https://a.com/callback
第二步 用户在B网站登录跳转到A网站
用户跳转到B网站,进行登录操作,登陆后会跳转到上一步的CALLBACK_URL
, 并携带一个code
https://a.com/callback?code=AUTHORIZATION_CODE
code
获得 token
第三步 A网站后端根据 A网站的callback
接收到code
参数,后端向B请求令牌
https://b.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL
其中,client_id
和client_secret
用来确认A的身份,grant_type
为authorization_code
表示授权码模式,code
是传过来的授权码,
redirect_uri
是令牌颁发后的回调地址。
第四步 B网站收到请求,颁发令牌
向第三步的回调地址发送一段json
数据
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101,
"info":{...}
}
此时 A网站便可以通过令牌 调用 B网站的接口了
Github OAuth2 实战
注册应用 获得 client_id 和 sercet
https://github.com/settings/applications/new
配置 回调地址
假设为 http://localhost/oauth/redirect
服务器实现
@RestController
public class OuathController {
@Autowired
RestTemplate restTemplate;
@Value("${github.client.ID}")
String clientID;
@Value("${github.client.secret}")
String clientSecret;
@RequestMapping("/oauth/redirect")
public String redirect(@RequestParam("code") String code) {
System.out.println("code: " + code);
// 通过 code 获得 access_token
String postUrl = "https://github.com/login/oauth/access_token";
//headers
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
requestHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
//body
Map<String, String> requestBody = new HashMap();
requestBody.put("client_id", clientID);
requestBody.put("client_secret", clientSecret);
requestBody.put("code", code);
HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(requestBody, requestHeaders);
Map<String, Object> s = restTemplate.postForObject(postUrl, requestEntity, Map.class);
String token = (String) s.get("access_token");
System.out.println("access token:" + token);
requestBody.clear();
requestHeaders.setBearerAuth(token);
requestEntity = new HttpEntity<>(requestBody, requestHeaders);
String userUrl = "https://api.github.com/user";
ResponseEntity<String> exchange = restTemplate.exchange(userUrl, HttpMethod.GET, requestEntity, String.class);
return exchange.getBody();
}
}
用户操作
用户通过 <a href="https://github.com/login/oauth/authorize?client_id=11d48799b5cbf9a06fb0&redirect_uri=http://localhost:8080/oauth/redirect">github</a>
跳转到 github
登录,授权后,用户会跳转到http://localhost:8080/oauth/redirect?code=a69488907d4ed78ce1c1
后台可以根据code
访问github
获得acess_token
,根据acess_token
便可获得用户的各种信息了