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";
    }
}

 

posted on 2020-03-11 01:18  -赶鸭子上架-  阅读(482)  评论(0编辑  收藏  举报