Github | ||
---|---|---|
上一篇 | 主目录 | 下一篇 |
【前言】
创建Github App
查看创建方法
GitHub主页底部API->Building a GitHub App or an OAuth App->右侧导航栏Building GitHub Apps,Creating a GitHub App
创建
setting->Developer settings->new github app->填写信息
GitHub授权登录流程
三段交互的过程
- 【1.1】点击登录按钮向GitHub服务器发送授权登录请求,登录绑定的超链接是:
<a th:href="@{https://github.com/login/oauth/authorize(client_id='1e6d67d6f6025830',redirect_uri=${#httpServletRequest.getServletContext().getAttribute('redirectUri')},scope='user',state=1)}">登录</a>
#或者
<a th:href="https://github.com/login/oauth/authorize?client_id=1e6d67d6f6025830&redirect_uri=http://localhost:8080/callback&scope=user&state=1">登录</a>
- 【1.2&&1.2.1】github收到授权请求后,回调
redirect_uri
(http://localhost:8080/callback,向本地服务器发送callback
请求),并携带code
和state
- 【1.2.1.1-1.2.1.4】本地服务器处理GitHub的回调请求
callback
:编写控制器AuthorizeController,通过Service层的authorizeService.getGithubUser(code,state)
获得GithubUser 对象,并验证GitHub是否授权了 - 【1.2.1.1&&1.2.1.2】如何去请求
access_token
?通过okhttp3向github去发送post
请求:https://github.com/login/oauth/access_token
,携带的参数是json格式的accessTokenDTO
。然后GitHub返回accessToken
- 【1.2.1.3&&1.2.1.4】通过accessToken去获取user的信息:发送请求
https://api.github.com/user?access_token="+accessToken
,获得json格式的user数据
具体实现
DTO数据传输对象:
@Data
public class AccessTokenDTO {
private String client_id;
private String client_secret;
private String code;
private String redirect_uri;
private String state;
}
@Data
public class GithubUser {
private String name;
private long id;
private String bio;
private String avatarUrl;
}
向GitHub获取AccessToken和GithubUser的组件:
@Component
public class GithubProvider {
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];
return token;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public GithubUser getUser(String accessToken){
OkHttpClient client=new OkHttpClient();
Request request=new Request.Builder()
.url("https://api.github.com/user?access_token="+accessToken)
.build();
try{
Response response=client.newCall(request).execute();
//System.out.println(response);
String string=response.body().string();
//System.out.println(string);
GithubUser githubUser = JSON.parseObject(string, GithubUser.class);
return githubUser;
}catch (IOException e){
e.printStackTrace();
}
return null;
}
}
service层提供服务:
@Service
public class TokenService {
@Value("Iv1.1e6d67d6f6025830")
private String clientId;
@Value("${github.client.secret}")
private String clientSecret;
@Value("${github.client.uri}")
private String clientUri;
public AccessTokenDTO initAccessTokenDTO(String code,String state){
AccessTokenDTO accessTokenDTO = new AccessTokenDTO();
accessTokenDTO.setClient_id(clientId);
accessTokenDTO.setClient_secret(clientSecret);
accessTokenDTO.setCode(code);
accessTokenDTO.setRedirect_uri(clientUri);
accessTokenDTO.setState(state);
//System.out.println(accessTokenDTO);
return accessTokenDTO;
}
}
@Service
public class AuthorizeService {
@Autowired
private GithubProvider githubProvider;
@Autowired
private TokenService tokenService;
@Autowired
private UserService userService;
public GithubUser getGithubUser(String code,String state){
AccessTokenDTO accessTokenDTO = tokenService.initAccessTokenDTO(code,state);
/**调用githubProvider.getAccessToken()方法获取accessToken*/
String accessToken = githubProvider.getAccessToken(accessTokenDTO);
System.out.println(accessToken);
/**获取GithubUser对象*/
GithubUser githubUser = githubProvider.getUser(accessToken);
//System.out.println(githubUser);
return githubUser;
}
public boolean githubAuthorize(GithubUser githubUser,
HttpServletRequest request,
HttpServletResponse response) {
if (githubUser != null) {/**授权登录成功,设置session和cookie,并存储到数据库中*/
Boolean githubUserExist = userService.githubUserExist(githubUser);
//System.out.println(githubUserExist);
if (!githubUserExist) {
userService.insertGithubUser(githubUser);
//System.out.println("insert");
} else {
userService.updateGithubUser(githubUser);
//System.out.println("update");
}
List<User> users = userService.getUser(githubUser);
String token = users.get(0).getToken();
request.getSession().setAttribute("user", githubUser);
response.addCookie(new Cookie("token",token));
return true;
}
return false;
}
}
controller控制业务逻辑:
@Controller
public class AuthorizeController {
@Autowired
private AuthorizeService authorizeService;
/**
* Github三方登录的回调函数
* Github授权的过程:
* 1.点击登录按钮(超链接地址是https://github.com/login/oauth/authorize?client_id=Iv1.1e6d67d6f6025830&redirect_uri=http://localhost:8080/callback&scope=user&state=1)向GitHub发送授权请求
* 2.GitHub验证成功后向重定向地址(redirect_uri=http://localhost:8080/callback)发送请求”/callback“,同时传回的参数有code和state
* 3.服务器处理请求”/callback“,即进入此函数
* 4.获得githubUser的信息:
* 4.1 向服务器获取accessToken
* 4.2 通过accessToken获取用户信息
* 5.githubAuthorize验证是否成功获得授权信息
* 6.授权成功,获取数据库中的相应GitHubUser信息,并重定向到主页;
* 授权失败,重定向到主页
*/
@GetMapping("/callback")
public String callback(@RequestParam(name = "code") String code,
@RequestParam(name = "state") String state,
HttpServletRequest request,
HttpServletResponse response){
GithubUser githubUser = authorizeService.getGithubUser(code,state);
boolean authorized = authorizeService.githubAuthorize(githubUser,request,response);
if(authorized){
//User user = userService.getUser(githubUser);
//System.out.println(user);
return "redirect:/";
}else{/**登录失败*/
return "redirect:/";
}
}
}