【第三方互聯】十四、Github授權第三方登錄

今天我們繼續學習:Github授權第三方登錄,前面我們已經學習了 碼雲(Gitee)授權第三方登錄,Github授權第三方登錄的實現過程其實和 碼雲(Gitee)授權第三方登錄的實現過程類似,只是有一些細節需要注意,下面我們就一起來學習吧

一、準備工作

首先我們得有自己的一個 githu 賬號,我們到 github 的官網進行註冊或者登錄

官網地址:https://github.com/

登錄成功後:
登錄成功界面

  • 2、創建應用

在下拉菜單中找到 “Settings”,設置
settings
然後找到 “Developer settings”,開發人員設置
Developer settings
找到“OAuth Apps”,我們就可以開始創建我們的授權應用了,在右上角點擊“New OAuth APP”
創建應用
我們填好應用基本信息,點擊“Register application”,我們便創建好了應用,點擊應用,我們便可以拿到應用的 appid 和 appkey
應用信息

  • 3、將應用信息保存到項目中

配置信息
由於我使用的是 SpringBoot 項目,我放在了 application.yml 文件中

二、開始開發

  • 1、引入 Maven 依賴
<!-- 網絡請求 -->
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
	<version>4.5.6</version>
</dependency>
<!-- alibaba的fastjson -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.51</version>
</dependency>

其餘的依賴請自行加入

  • 2、在頁面放置 “Github” 授權登錄的 DOM 元素
<a th:href="@{github/auth}" class="link" title="Github登錄"><i class="iconfont icon-github"></i></a>

這裏使用的是阿里的 iconfont 圖標

三、接口類

創建 “Github” 授權登錄的 Controller,GithubController.java

  • 1、從配置文件中獲取 “Github” 配置信息
/**
 * github授權中提供的 appid 和 appkey
 */
@Value("${github.oauth.clientid}")
public String CLIENTID;
@Value("${github.oauth.clientsecret}")
public String CLIENTSECRET;
@Value("${github.oauth.callback}")
public String URL;
  • 2、頁面登錄按鈕點擊後的接口
/**
 * 請求授權頁面
 */
@GetMapping(value = "/auth")
public String qqAuth(HttpSession session) {
    // 用於第三方應用防止CSRF攻擊
    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
    session.setAttribute("state", uuid);

    // Step1:獲取Authorization Code
    String url = "https://github.com/login/oauth/authorize?scope=user" +
            "&client_id=" + CLIENTID +
            "&redirect_uri=" + URLEncoder.encode(URL) +
            "&state=" + uuid;

    return PasswordUtils.redirectTo(url);
}

接口文檔中建議我們在授權登錄時傳入一個加密的數據防止被攻擊,我們傳入了UUID,最後重定向到授權頁面
授權頁面

  • 3、當該用戶點擊“授權”按鈕,同意授權後,就會回調到我們在應用中填寫的回調地址裏去
/**
 * 授權回調
 */
@GetMapping(value = "/callback")
public String qqCallback(HttpServletRequest request) throws Exception {
    HttpSession session = request.getSession();
    // 得到Authorization Code
    String code = request.getParameter("code");
    // 我們放在地址中的狀態碼
    String state = request.getParameter("state");
    String uuid = (String) session.getAttribute("state");

    // 驗證信息我們發送的狀態碼
    if (null != uuid) {
        // 狀態碼不正確,直接返回登錄頁面
        if (!uuid.equals(state)) {
            return PasswordUtils.redirectTo("/login");
        }
    }

    // Step2:通過Authorization Code獲取Access Token
    String url = "https://github.com/login/oauth/access_token?" +
            "client_id=" + CLIENTID +
            "&client_secret=" + CLIENTSECRET +
            "&redirect_uri=" + URL +
            "&code=" + code +
            "&state=" + state;
    JSONObject accessTokenJson = GithubHttpClient.getAccessToken(url);

    // Step3: 獲取用戶信息
    /*url = "https://api.github.com/user?access_token=" + accessTokenJson.getString("access_token");*/
    url = "https://api.github.com/user";
    JSONObject jsonObject = GithubHttpClient.getUserInfo(url, accessTokenJson.getString("access_token"));
    
    /**
     * TODO 獲取到用戶信息之後,你自己的業務邏輯
     * 判斷數據庫是否有次用戶,有---登錄成功,無---保存用戶至數據庫,登錄成功
     */

    return PasswordUtils.redirectTo("/success");
}

四、網絡請求方法

上面回調方法中所用到的網絡接口方法,我放在了 GithubHttpClient.java 文件中,主要有兩個方法

  • 1、使用 code 獲取Access Token
/**
 * 獲取Access Token
 * post
 */
public static JSONObject getAccessToken(String url) throws IOException {
    HttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(url);
    httpPost.setHeader("Accept", "application/json");
    HttpResponse response = client.execute(httpPost);
    HttpEntity entity = response.getEntity();
    if (null != entity) {
        String result = EntityUtils.toString(entity, "UTF-8");
        return JSONObject.parseObject(result);
    }
    httpPost.releaseConnection();
    return null;
}

我們在請求頭中傳入了

httpPost.setHeader("Accept", "application/json");

是希望返回 JSON 格式的數據,code 直接拼接在了 url 上

  • 2、使用 Access Token 獲取用戶信息
/**
 * 獲取用戶信息
 * get
 */
public static JSONObject getUserInfo(String url, String token) throws IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpGet httpGet = new HttpGet(url);
    httpGet.setHeader("Accept", "application/json");
    httpGet.setHeader("Authorization", "token " + token);
    HttpResponse response = client.execute(httpGet);
    HttpEntity entity = response.getEntity();
    if (entity != null) {
        String result = EntityUtils.toString(entity, "UTF-8");
        return JSONObject.parseObject(result);
    }
    httpGet.releaseConnection();
    return null;
}

獲取用戶信息這一步,官方給的文檔是:
獲取用戶信息
注意:這裏我們在請求頭中傳入 token,API 文檔中描述不夠清楚,這裏看了好幾遍才明白,掉坑兒裏了

httpGet.setHeader("Authorization", "token " + token);

最終我們獲取到一個 JSON 對象,該對象包含了用戶的信息,例如:id,name,email,phone 等等。

  • 3、官網 OAuth API 文檔
https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/#web-application-flow

五、總結

該授權認證過程符合 OAuth2 認證基本流程,流程如下:
OAuth2授權認證流程

1、用戶點擊頁面登錄按鈕,請求授權頁面,用戶在此頁面登錄賬號並同意授權
2、用戶同意授權後,回調至我們項目中,首先驗證 state 是否一致
3、使用上一步拿到的 code 請求 access_token
4、使用 access_token 請求 用戶信息,完成授權登錄過程

如您在閱讀中發現不足,歡迎留言!!!

下一篇:

【第三方互聯】十五、百度(baidu)授權第三方登錄

如您在閱讀中發現不足,歡迎留言!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章