日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

快速接入 GitHub、QQ 第三方登录方式

發布時間:2025/3/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 快速接入 GitHub、QQ 第三方登录方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
點擊上方?好好學java?,選擇?星標?公眾號重磅資訊,干貨,第一時間送達 今日推薦:推薦 19 個 github 超牛逼項目!個人原創100W +訪問量博客:點擊前往,查看更多

本文提及第三方登錄涉及到 OAuth2.0,關于 OAuth2.0 的理論基礎參考阮一峰老師的《理解 OAuth 2.0》,其中關于授權碼模式就是本篇文章的重點,如想看這篇理論基礎自行百度即可。

本文著重于代碼,關于理論不再贅述,關于不同公司的三方登錄流程,只要遵循 OAuth2.0 規范,都大同小異。本文介紹 GitHub 和 QQ 兩種,因為這兩種無需審核,即可食用。歷史也發布過 Spring Boot 的其他實戰,可以關注微信公眾號「Java后端」回復「666」下載技術棧手冊。

一、GitHub 登錄

1.1 注冊應用

進入 Github 的 Setting 頁面,點擊 Developer settings,如圖所示:

進入后點擊 New Oauth App,如圖所示:

在其中填寫主頁 URL 和 回調 URL,回調 URL 尤為重要,如果不太明白可以先和我一致。

點擊注冊后,上方會生成 Client ID 和 Client Secret,這兩個后面要用到。

1.2 HTML 頁面

頁面十分簡單,只有兩個跳轉鏈接:

<!DOCTYPE html> <html?lang="en"> <head><meta?charset="UTF-8"><title>三方登錄</title> </head> <body><h1>三方登錄Demo</h1><div><a?href="/githubLogin">GitHub登錄</a><a?href="/qqLogin">QQ登錄</a></div> </body> </html>

1.3 Github 登錄方法

在這個方法中,我們需要訪問 GitHub 的認證服務器,使用 Get 請求,這里使用重定向來實現。

遵循 Oauth 2.0 規范,需要攜帶以下參數:

  • response_type :對于授權碼模式,該值固定為 code

  • client_id :注冊應用時的 Client ID

  • state :回調時會原樣返回

  • redirect_uri : 回調 URL,注冊應用時填寫的

這里的 state 參數我要額外說明下,因為該參數會在后面的回調 URL 中被原樣攜帶回來,絕大多數的開發者會忽略該字段,阮一峰老師的文章也沒有著重提及這一點。但是忽略該參數是會導致 CSRF攻擊的,在回調函數中應當對該字段進行校驗!

關于如何校驗,我一開始的想法是使用 session 來存儲 state 進行校驗的,但是我發現使用重定向后 session 不是同一個 session,方案一失敗。

然后我想通過 ajax 請求,在頁面中使用 window.location.href 方法跳轉到認證服務器,使用 session 存儲,但是很不幸這樣也不是同一個 session,方案二失敗。

最后我的解決辦法是使用 redis 緩存,使用 set 存儲,回調時判斷是否存在。當然你也可以用 HashMap 來存儲,這也是一個解決辦法。

關于 Redis,可以參考:https://jitwxs.cn/e331e26a.html

private?static?String?GITHUB_CLIENT_ID = "0307dc634e4c5523cef2"; private?static?String?GITHUB_CLIENT_SECRET = "707647176eb3bef1d4c2a50fcabf73e0401cc877"; private?static?String?GITHUB_REDIRECT_URL = "http://127.0.0.1:8080/githubCallback";@RequestMapping("/githubLogin") public?void?githubLogin(HttpServletResponse response) throws Exception {// Github認證服務器地址String?url = "https://github.com/login/oauth/authorize";// 生成并保存state,忽略該參數有可能導致CSRF攻擊String?state = oauthService.genState();// 傳遞參數response_type、client_id、state、redirect_uriString?param = "response_type=code&"?+ "client_id="?+ GITHUB_CLIENT_ID + "&state="?+ state+ "&redirect_uri="?+ GITHUB_REDIRECT_URL;// 1、請求Github認證服務器response.sendRedirect(url + "?"?+ param); }

1.4 Github 回調方法

在上一步中,瀏覽器會被跳轉到 Github 的授權頁,當用戶登錄并點擊確認后,GitHub認證服務器會跳轉到我們填寫的回調URL中,我們在程序中處理回調。

在回調方法中,步驟如下:

1. 首先驗證 state 與發送時是否一致,如果不一致,可能遭遇了 CSRF 攻擊。

2. 得到 code,向 GitHub 認證服務器申請令牌(token)

??這一步使用模擬的 POST 請求,攜帶參數包括:

  • grant_type :授權碼模式固定為 authorization_code

  • code :上一步中得到的 code

  • redirect_uri :回調URL

  • client_id :注冊應用時的Client ID

  • client_secret :注冊應用時的Client Secret

3. 得到令牌(access_token)和令牌類型(token_type),向GitHub資源服務器獲取資源(以 user_info 為例)

這一步使用模擬的 GET 請求,攜帶參數包括:

  • access_token :令牌

  • token_type :令牌類型

4. 輸出結果

/*** GitHub回調方法* @param code 授權碼* @param state 應與發送時一致* @author jitwxs* @since 2018/5/21 15:24*/ @RequestMapping("/githubCallback") public?void?githubCallback(String?code, String?state, HttpServletResponse response) throws Exception {// 驗證state,如果不一致,可能被CSRF攻擊if(!oauthService.checkState(state)) {throw?new?Exception("State驗證失敗");}// 2、向GitHub認證服務器申請令牌String?url = "https://github.com/login/oauth/access_token";// 傳遞參數grant_type、code、redirect_uri、client_idString?param = "grant_type=authorization_code&code="?+ code + "&redirect_uri="?+GITHUB_REDIRECT_URL + "&client_id="?+ GITHUB_CLIENT_ID + "&client_secret="?+ GITHUB_CLIENT_SECRET;// 申請令牌,注意此處為post請求String?result = HttpClientUtils.sendPostRequest(url, param);/** result示例:* 失敗:error=incorrect_client_credentials&error_description=The+client_id+and%2For+client_secret+passed+are+incorrect.&* error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-oauth-app-access-token-request-errors%2F%23incorrect-client-credentials* 成功:access_token=7c76186067e20d6309654c2bcc1545e41bac9c61&scope=&token_type=bearer*/Map<String, String> resultMap = HttpClientUtils.params2Map(result);// 如果返回的map中包含error,表示失敗,錯誤原因存儲在error_descriptionif(resultMap.containsKey("error")) {throw??new?Exception(resultMap.get("error_description"));}// 如果返回結果中包含access_token,表示成功if(!resultMap.containsKey("access_token")) {throw??new?Exception("獲取token失敗");}// 得到token和token_typeString?accessToken = resultMap.get("access_token");String?tokenType = resultMap.get("token_type");// 3、向資源服務器請求用戶信息,攜帶access_token和tokenTypeString?userUrl = "https://api.github.com/user";String?userParam = "access_token="?+ accessToken + "&token_type="?+ tokenType;// 申請資源String?userResult = HttpClientUtils.sendGetRequest(userUrl, userParam);// 4、輸出用戶信息response.setContentType("text/html;charset=utf-8");response.getWriter().write(userResult); }

二、QQ 登錄

2.1 注冊應用

進入 QQ 互聯管理中心:https://connect.qq.com/manage.html,創建一個新應用(需要先審核個人身份):

然后注冊應用信息,和 GitHub 的步驟大差不差:

注冊后,可以看到應用的 APP ID、APP Key,以及你被允許的接口,當然只有一個獲取用戶信息。

官方開發文檔點擊這里:

http://wiki.connect.qq.com/%E5%BC%80%E5%8F%91%E6%94%BB%E7%95%A5_server-side

注意:審核狀態為審核中和審核失敗也是可以使用的,不用擔心(只是無法實際上線而已,作為 Demo 足夠了)。

2.2 QQ 登錄方法

private?static?String?QQ_APP_ID = "101474821"; private?static?String?QQ_APP_KEY = "00d91cc7f636d71faac8629d559f9fee"; private?static?String?QQ_REDIRECT_URL = "http://127.0.0.1:8080/qqCallback";@RequestMapping("/qqLogin") public?void?qqLogin(HttpServletResponse response) throws Exception {// QQ認證服務器地址String?url = "https://graph.qq.com/oauth2.0/authorize";// 生成并保存state,忽略該參數有可能導致CSRF攻擊String?state = oauthService.genState();// 傳遞參數response_type、client_id、state、redirect_uriString?param = "response_type=code&"?+ "client_id="?+ QQ_APP_ID + "&state="?+ state+ "&redirect_uri="?+ QQ_REDIRECT_URL;// 1、請求QQ認證服務器response.sendRedirect(url + "?"?+ param); }

2.3 QQ 回調方法

/*** QQ回調方法* @param code 授權碼* @param state 應與發送時一致* @author jitwxs* @since 2018/5/21 15:24*/ @RequestMapping("/qqCallback") public?void?qqCallback(String?code, String?state, HttpServletResponse response) throws Exception {// 驗證state,如果不一致,可能被CSRF攻擊if(!oauthService.checkState(state)) {throw?new?Exception("State驗證失敗");}// 2、向QQ認證服務器申請令牌String?url = "https://graph.qq.com/oauth2.0/token";// 傳遞參數grant_type、code、redirect_uri、client_idString?param = "grant_type=authorization_code&code="?+ code + "&redirect_uri="?+QQ_REDIRECT_URL + "&client_id="?+ QQ_APP_ID + "&client_secret="?+ QQ_APP_KEY;// 申請令牌,注意此處為post請求// QQ獲取到的access token具有3個月有效期,用戶再次登錄時自動刷新。String?result = HttpClientUtils.sendPostRequest(url, param);/** result示例:* 成功:access_token=A24B37194E89A0DDF8DDFA7EF8D3E4F8&expires_in=7776000&refresh_token=BD36DADB0FE7B910B4C8BBE1A41F6783*/Map<String, String> resultMap = HttpClientUtils.params2Map(result);// 如果返回結果中包含access_token,表示成功if(!resultMap.containsKey("access_token")) {throw??new?Exception("獲取token失敗");}// 得到tokenString?accessToken = resultMap.get("access_token");// 3、使用Access Token來獲取用戶的OpenIDString?meUrl = "https://graph.qq.com/oauth2.0/me";String?meParams = "access_token="?+ accessToken;String?meResult = HttpClientUtils.sendGetRequest(meUrl, meParams);// 成功返回如下:callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} );// 取出openidString?openid = getQQOpenid(meResult);// 4、使用Access Token以及OpenID來訪問和修改用戶數據String?userInfoUrl = "https://graph.qq.com/user/get_user_info";String?userInfoParam = "access_token="?+ accessToken + "&oauth_consumer_key="?+ QQ_APP_ID + "&openid="?+ openid;String?userInfo = HttpClientUtils.sendGetRequest(userInfoUrl, userInfoParam);// 5、輸出用戶信息response.setContentType("text/html;charset=utf-8");response.getWriter().write(userInfo); }/*** 提取Openid* @param str 形如:callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} );* @author jitwxs* @since 2018/5/22 21:37*/ private?String?getQQOpenid(String?str) {// 獲取花括號內串String?json = str.substring(str.indexOf("{"), str.indexOf("}") + 1);// 轉為MapMap<String, String> map = JsonUtils.jsonToPojo(json, Map.class);return?map.get("openid"); }

三、項目源碼

QQ 登錄的具體流程我就不啰嗦了,都差不多。代碼只列出了關鍵方法,具體程序還包含工具類和 redis 的配置。具體請參考文章開頭源碼,該項目采用 SpringBoot 搭建,需要 Redis 支持。

文章作者: Jitwxs

文章鏈接: https://jitwxs.cn/33ad9e35.html

版權聲明: 本博客所有文章除特別聲明外,均采用 CC BY-NC-SA 4.0 許可協議。轉載請注明來自 Jitwxs!

推薦文章
  • 基于SpringBoot的ERP系統,自帶進銷存+財務+生產功能

  • 2020年國內互聯網公司的薪酬排名!

  • 不要再封裝各種Util工具類了,這個神級框架值得擁有!

  • 寫博客能月入10K?

  • 一款基于 Spring Boot 的現代化社區(論壇/問答/社交網絡/博客)

更多項目源碼
  • 這或許是最美的Vue+Element開源后臺管理UI

  • 推薦一款高顏值的 Spring Boot 快速開發框架

  • 一款基于 Spring Boot 的現代化社區(論壇/問答/社交網絡/博客)

  • 13K點贊都基于 Vue+Spring 前后端分離管理系統ELAdmin,大愛

  • 想接私活時薪再翻一倍,建議根據這幾個開源的SpringBoot項目

總結

以上是生活随笔為你收集整理的快速接入 GitHub、QQ 第三方登录方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。