Github授权登录第三方

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.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. 【1.2&&1.2.1】github收到授权请求后,回调redirect_uri(http://localhost:8080/callback,向本地服务器发送callback请求),并携带codestate
  2. 【1.2.1.1-1.2.1.4】本地服务器处理GitHub的回调请求callback:编写控制器AuthorizeController,通过Service层authorizeService.getGithubUser(code,state)获得GithubUser 对象,并验证GitHub是否授权了
  3. 【1.2.1.1&&1.2.1.2】如何去请求access_token?通过okhttp3向github去发送post请求:https://github.com/login/oauth/access_token,携带的参数是json格式的accessTokenDTO。然后GitHub返回accessToken
  4. 【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:/";
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值