GitHub第三方登录实现效果如下:


实现GitHub第三方登陆详细过程 - 图1

实现流程如下:


实现GitHub第三方登陆详细过程 - 图2

1.注册一个GitHub账号 2.注册一个授权的网站 保存一个你的Client ID和Client Secret 3.准备一个页面,有一个链接跳转到授权的页面 GitHub](https://github.com/login/oauth/authorize?client_id=xx&state=STATE&redirect_uri=xx”>GitHub)登录 4.准备controller去处理callback回调的请求 ① 获取到请求参数中的code ② 拿到code去发送请求请求token ③ 拿到token发送请求请求用户信息 ④ 将用户信息做持久化处理(放到请求范围中) ⑤ 在主页面通过el表单获取到前面取到的用户信息…

创建GitHub 应用程序地址:

https://docs.github.com/en/developers/apps/creating-a-github-app

实现GitHub第三方登陆详细过程 - 图3

GitHub第三方登录的认证授权API流程地址:


https://docs.github.com/en/developers/apps/identifying-and-authorizing-users-for-github-apps

实现GitHub第三方登陆详细过程 - 图4

1.1 GitHub第三方登录的认证授权流程


申请 Client ID 和 ClientSecret

首先到GitHub官网注册账号: https://github.com/

实现GitHub第三方登陆详细过程 - 图5

登录:https://github.com/login

实现GitHub第三方登陆详细过程 - 图6

登录进去之后点击你的头像,选择Settings

实现GitHub第三方登陆详细过程 - 图7

选择左下方的Developer settings创建一个应用

实现GitHub第三方登陆详细过程 - 图8

实现GitHub第三方登陆详细过程 - 图9

注册应用之后,可以获取到Client ID和 Client Secret

实现GitHub第三方登陆详细过程 - 图10

1.2 申请clientID和clientSecret的用途???

clientID:应用的唯一标识。

clientSecret:clientID对应的密钥,访问用户资源时用来验证应用的合法性。

申请地址: https://github.com/settings/developers

注意:对clientID和clientSecret信息进行保密,不要随意泄漏。

1.3 GitHub的登录授权实现

第三方登录流程是:先获取code —> 然后获取access_token —> 根据token获取用户信息。 前台页面实现步骤:点击登录按钮 —> 打开一个窗口,进行授权 —> 授权完成,跳转到首页或上次浏览的页面。

1. 请求用户的 GitHub 身份

GET https://github.com/login/oauth/authorize

前台准备一个页面,有一个链接跳转到GitHub的授权页面

例如:

登录

  1. https://github.com/login/oauth/authorize?client_id=xx&state=xx&redirect_uri=xx;

参数:

名字 类型 描述
client_id string 需要。GitHub 应用程序的客户端 ID。当您选择应用时,您可以在GitHub 应用设置中找到此问题。
redirect_uri string 应用程序中的网址,用户将在授权后发送。这必须与您在设置 GitHub 应用程序时作为回拨 URL提供的 URL 之一精确匹配,并且不能包含任何其他参数。
state string 这应该包含一个随机字符串,以防止伪造攻击,并可能包含任何其他任意数据。
login string 建议使用特定帐户登录和授权应用程序。
allow_signup string 在 OAuth 流期间,是否为未经授权的用户提供注册 GitHub 的选项。默认值是 .当策略禁止注册时使用。truefalse

实现GitHub第三方登陆详细过程 - 图11

点击跳转到GitHub第三方登录页面

实现GitHub第三方登陆详细过程 - 图12

实现GitHub第三方登陆详细过程 - 图13

登录账号进行授权

实现GitHub第三方登陆详细过程 - 图14

授权之后就会跳转到自己之前创建应用时设置的回调路径

温馨小提示:如果是本地测试可将回调地址修改成本地路径 实现GitHub第三方登陆详细过程 - 图15

2. GitHub 将用户重定向回您的网站

如果用户接受您的请求,GitHub 将通过代码参数中的临时状态以及您在参数上一步提供的状态重定向回您的网站。如果状态不匹配,请求由第三方创建,并且该过程应中止。codestate

POST https://github.com/login/oauth/access_token

参数:

名字 类型 描述
client_id string 需要。GitHub 应用程序的客户端 ID。
client_secret string 需要。您的GitHub应用程序的客户端秘密。
code string 需要。您收到的代码作为对步骤 1 的响应。
redirect_uri string 应用程序中的网址,用户将在授权后发送。这必须与您在设置 GitHub 应用程序时作为回拨 URL提供的 URL 之一精确匹配,并且不能包含任何其他参数。
state string 您在第 1 步中提供的不可用的随机字符串。

响应

默认情况下,响应采用以下形式。响应参数,并且仅在启用即将到期的用户到服务器访问令牌时返回。expires_inrefresh_tokenrefresh_token_expires_in

实现GitHub第三方登陆详细过程 - 图16

代码:

1)导入pom依赖

com.squareup.okhttp3 okhttp 4.9.0

地址:https://square.github.io/okhttp/

实现GitHub第三方登陆详细过程 - 图17

2)编写用来封装请求参数对象

package com.gmw.communtity.dto;

import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import lombok.experimental.Accessors;

/** * 用来封装请求参数对象 */ @Data @AllArgsConstructor @NoArgsConstructor @ToString @Accessors(chain = true) public class AccessTokenDTO { private String client_id; //客户端ID private String client_secret; //客户端密码 private String code; //步骤1的响应的代码 private String redirect_uri; //回调URL private String state; //步骤1中提供的不可猜测的随机字符串 }

3)用来封装返回用户的信息

package com.gmw.communtity.dto;

import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import lombok.experimental.Accessors;

/** * 用来封装返回用户的信息 */ @Data @AllArgsConstructor @NoArgsConstructor @ToString @Accessors(chain = true) public class GithubUser { private String name; //用户的昵称 private Long id; //用户的唯一id private String bio; //用户的描述 private String avatar_url; //用户的头像 }

4)编写通过code获取access_token的方法,在通过access_token获取用户信息的方法

package com.gmw.communtity.provider;

import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.gmw.communtity.dto.AccessTokenDTO; import com.gmw.communtity.dto.GithubUser; import okhttp3.*; import org.springframework.stereotype.Component;

import java.io.IOException;

/** * 表示提供第三方客户端请求的服务 OKHttp */ @Component public class GitHubProvider { /** * 获取AccessToken的方法 */ _public String getAcccessToken(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 data = response.body().string();


        String[] split = data.split("&");
        String tokenStr = split[0];
        String token = tokenStr.split("=")[1];

        System._out_.println("accessToken = " + token);

        return token;
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

_/**_

* 通过accessToken,获取用户的信息 */ _ _public GithubUser getUser(String assessToken){ OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url(“https://api.github.com/user“) .header(“Authorization”,”token “+ assessToken) .build();

    try (Response response = client.newCall(request).execute()) {
        String resp = response.body().string();
        GithubUser githubUser = JSON._parseObject_(resp, GithubUser.class);
        return githubUser;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

}

5)编写授权成功后,返回首页的回调方法

package com.gmw.communtity.controller;

import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.core.JsonProcessingException; import com.gmw.communtity.dto.AccessTokenDTO; import com.gmw.communtity.dto.GithubUser; import com.gmw.communtity.entity.User; import com.gmw.communtity.provider.GitHubProvider; import com.gmw.communtity.service.UserService; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.UUID;

@Controller public class AuthorizeController { @Autowired private GitHubProvider gitHubProvider;

@Autowired
private UserService userService;

@Value("${github.client.id}")
private String clientId;
@Value("${github.client.secret}")
private String clientSecret;
@Value("${github.client.url}")
private String redirectUri;

_/**_

* 授权成功后,返回首页 * @return */ @GetMapping(value = “/callback”) public String callback(@RequestParam(name = “code”) String code, @RequestParam(name = “state”) String state, HttpServletRequest request, HttpServletResponse response) {

    AccessTokenDTO accessTokenDTO = new AccessTokenDTO();

    //客户端ID
    accessTokenDTO.setClient_id(clientId);
    //客户端密码
    accessTokenDTO.setClient_secret(clientSecret);
    //步骤1的响应的代码
    accessTokenDTO.setCode(code);
    //回调URL
    accessTokenDTO.setRedirect_uri(redirectUri);
    //步骤1中提供的不可猜测的随机字符串
    accessTokenDTO.setState(state);

    //通过调用getAcccessToken()方法获取token
    String acccessToken = gitHubProvider.getAcccessToken(accessTokenDTO);

    //通过token获取用户的信息
    GithubUser githubUser = gitHubProvider.getUser(acccessToken);


    System._out_.println(githubUser);

    //判断获取到的用户信息是否为空
    if(githubUser != null && githubUser.getId() != null){

        User user = new User();
        //生成的随机字符串,通过cookie发送到浏览保存,下次请求的时候,携带cookie,原来判断该用户是否登录状态
        //可以防止,当服务器重新启动的时候,就不用频繁的登录
        String token = UUID._randomUUID_().toString();
        user.setToken(token);
        //用户的简介
        user.setBio(githubUser.getBio());
        //用户的名称
        user.setName(githubUser.getName());
        //用户的唯一ID
        user.setAccountId(String._valueOf_(githubUser.getId()));
        //用户的头像
        user.setAvatarUrl(githubUser.getAvatar_url());

        //将登录的用户信息保存到数据库中
        userService.createOrUpdate(user);

        //发送cookie到浏览器
        Cookie cookie = new Cookie("token",token);
        response.addCookie(cookie);


        //登录成功,写cookie和session
        //request.getSession().setAttribute("user",u);
        return "redirect:/";
    }else{
        //登录失败,重新登录
        return "redirect:/";
    }
}

//退出接口
@GetMapping(value = "/logout")
public String logout(HttpServletRequest request,HttpServletResponse response){
    request.getSession().removeAttribute("user");
    Cookie cookie = new Cookie("token",null);
    cookie.setMaxAge(0);
    response.addCookie(cookie);

    return "redirect:/";
}

}

3. 您的 GitHub 应用程序使用用户的访问令牌访问 API

用户的访问令牌允许 GitHub 应用程序代表用户向 API 提出请求。

Authorization: token OAUTH-TOKEN
GET https://api.github.com/user

获得用户的信息

实现GitHub第三方登陆详细过程 - 图18

代码最后运行结果: 可根据自己的需求去拿数据

实现GitHub第三方登陆详细过程 - 图19

实现GitHub第三方登陆详细过程 - 图20

温馨小提示:可在GitHub上https://github.com/settings/applications 取消授权的应用

实现GitHub第三方登陆详细过程 - 图21