1.首先就是要去自己的GitHub上去注册一个OAuth应用,详细步骤见:https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/
2.然后就是,我们需要在用户登录时,请求用户的GitHub身份,也就是在登录时,响应的URL应该为https://github.com/login/oauth/authorize,这样点击登录之后它就会跳转到这个网址,但是光是这个网址是不够的,因为并没有写明我们要携带的信息,我们必须携带以下信息:
对于第一个选项,我们在注册GitHub的OAuth应用时,会生成一个Client ID和一个Client Secret ,这个Client ID就是和这里的相对应。然后后面的redirect URL 就是我们经过Github认证后,它会重定向到的地址。举个栗子,我们经过登录界面,点击登录按钮之后,经过我们的GitHub认证,登录成功,我们是要跳转到首页的,那么这里的首页,也就是我们的redirect url 。第三个参数,login ,是必须要带的,state暂且没有用到,目前是一个写死的123,不是随机字符串。scope代表的是你需要从Github上获得哪些东西,就像只是获得用户名,还是基本资料都获得到。综上。我自己的项目的,URL就变成了:https://github.com/login/oauth/authorize?client_id=4dc14c753a4098d74da9&redirect_uri=http://localhost:8080/callback&scope=user&state=123
3.当用户同意授权给你的时候,GitHub重定向回你的网站,这时候,它会带着一个code和我们自己的state:http://localhost:8080/callback?code=ab865a75ff0a5860d7aa&state=123 这个时候我们要去GitHub去拿到用户的令牌,这样才可以通过令牌去得到用户的信息。
4.这个时候,我们需要在控制器写一个方法,当跳转到CallBack时,我们就需要调用这个方法,去对应的网址去请求到我们的用户信息。上面也看到了,我们需要携带的信息很多,所以我们为了程序的可读性,我们封装一个DTO,用来携带这些必要的信息,下面是代码片段,对应的set get方法就不贴了
public class AccessTokenDTO {
private String client_id;
private String redirect_uri;
private String client_secret;
private String code;
private String state;
}
我们将得到的信息,也就是code和state,和我们用户自己的信息,封装成一个DTO对象后。然后我们利用OKHTTP,用它来对GitHub相应的网址发送请求,然后返回我们需要的令牌,也就是token:
public String getAccessToken(AccessTokenDTO accessTokenDTO){
MediaType mediaType = MediaType.get("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(accessTokenDTO));
Request request = new Request.Builder()
.url("https://github.com/login/oauth/access_token")
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
String string=response.body().string();
String token=string.split("&")[0].split("=")[1];
System.out.println(string);
System.out.println(token);
return token;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
5.我们拿到token之后,我们就需要在对应的网站里面去拿到我们所需要的用户信息了。这个时候,我们向对应的网址发送请求:
public GitHubUsers getUser(String access_Token){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
//涉及到URL的地方,一定一定要确保没有空格,该错误导致一小时时间浪费,吸取教训。
.url("https://api.github.com/user?access_token="+access_Token)
.build();
try {
Response response = client.newCall(request).execute();
String string = response.body().string();
//System.out.println(string);
GitHubUsers gitHubUsers=JSON.parseObject(string,GitHubUsers.class);
//System.out.println(gitHubUsers.getId());
return gitHubUsers;
}catch (IOException e){
e.printStackTrace();
}
return null;
}
6.这个时候,我们可以通过取得的用户是不是为空,如果为空的话就是登录失败,不为空,那我们就显示登录成功,在前端显示用户的姓名,并且将用户信息写到我们的数据库里面。完成登录。