OAuth 2.0实践
关于OAuth 2.0的授权机制已经有不少博客讲解,比较通俗易懂的可以参考这里。
今天做个java版本的实践。
1) 拿自己的本本做服务器A,利用springboot启动web服务,浏览器访问http://localhost:8080,默认页index.html内容如下并放在/resources/static路径下。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> a { font-size: 2em } </style> </head> <body> <a href="https://github.com/login/oauth/authorize?client_id=9e4ff8eb94737f0baed4&redirect_uri=http://localhost:8080/oauth"> Login with GitHub </a> </body> </html>
如上链接将访问服务器B即GitHub的oauth接口,其中的client_id需要A站点到GitHub这里申请(用人家的数据毕竟得先让人家知道你的身份)。
申请后会得到GitHub分发给站点A的client id和client secret。
- client id用于获取GitHub认证码code
- client id + client secret + code用于获取access token
2) 点击链接后,GitHub要求用户登录并授权站点A获取相应数据,随后跳转回redirect_uri指定的url,此时的url包含参数code值,比如http://localhost:8080/oauth?code=c26c4d0d6e52b32db593
3) 拦截跳转后的url获取code值,然后利用client_id,client_secret,code请求GitHub access token,最后利用access token调用GitHub api获取用户数据。
@RestController public class OAuthController { @Autowired private RestTemplate restTemplate; @RequestMapping("/oauth") public String oauth(@RequestParam("code") String code){ //get access token via authorized code String tokenReq = "https://github.com/login/oauth/access_token?client_id=9e4ff8eb94737f0baed4" + "&client_secret=replace_yours" + "&code=" + code; ResponseEntity<String> respStr = restTemplate.postForEntity(tokenReq, null, String.class); String[] params = respStr.getBody().split("&"); String token_type = null, access_token = null; for (String param : params) { if (param.startsWith("access_token=")) { access_token = param.substring(param.indexOf("=") + 1); } if (param.startsWith("token_type=")) { token_type = param.substring(param.indexOf("=") + 1); } } //access api via token in header String result = null; if (token_type != null && access_token != null) { HttpHeaders headers = new HttpHeaders(); headers.add("accept", "application/json"); headers.add("Authorization", token_type + " " + access_token); HttpEntity httpEntity = new HttpEntity(headers); ResponseEntity<String> resp = restTemplate.exchange("https://api.github.com/user", HttpMethod.GET, httpEntity, String.class); result = resp.getBody(); } return result != null ? result : "error occurs"; } }
清醒时做事,糊涂时读书,大怒时睡觉,独处时思考; 做一个幸福的人,读书,旅行,努力工作,关心身体和心情,成为最好的自己
-- 共勉