手把手教你實現(xiàn)Java第三方應(yīng)用登錄
大家在自己做項目的時候有沒有想過實現(xiàn)一個第三方應(yīng)用登錄呢?類似這種:
本篇文章就來聊一聊該如何實現(xiàn)第三方應(yīng)用登錄。
什么是OAuth2.0
OAuth是一項協(xié)議,它為用戶資源的授權(quán)提供了一個安全、開放而簡易的標準,OAuth的授權(quán)不會使第三方觸及到用戶的賬號信息(比如密碼),因此OAuth是相對安全的。而OAuth2.0就是OAuth的延續(xù),不過2.0更加關(guān)注客戶端開發(fā)者的簡易性。
申請網(wǎng)站接入
常見的第三方應(yīng)用都支持第三方登錄,比如:QQ、微信、微博、GitHub、Gitee等,要想申請第三方登錄權(quán)限,就需要去到對應(yīng)的平臺,比如QQ,搜索QQ開放平臺:
進入應(yīng)用管理,并創(chuàng)建應(yīng)用即可:
不過對于QQ、微信、微博等的網(wǎng)站接入都需要身份認證,過程比較繁瑣,所以我們使用Gitee作為第三方應(yīng)用進行接入。
首先打開Gitee,選擇設(shè)置:
在設(shè)置中選擇第三方應(yīng)用:
點擊創(chuàng)建應(yīng)用并填寫相關(guān)信息:
應(yīng)用名稱可以隨意填寫,但是下面的兩個地址就有用途了,對于應(yīng)用主頁,它需要填寫的是當前應(yīng)用的主頁,而應(yīng)用回調(diào)接口填寫的是當?shù)卿洺晒笮枰D(zhuǎn)的頁面。
創(chuàng)建SpringBoot應(yīng)用
申請完成后,就可以來創(chuàng)建SpringBoot應(yīng)用,并新建一個index.html頁面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form> 用戶名:<input type="text"/><br/> 密碼:<input type="password"/><br/> <a href="">Gitee登錄</a> <input type="submit" value="登錄"/><br/> </form> </body> </html>
效果如下:
頁面很丑,但不重要,實現(xiàn)功能即可。
現(xiàn)在我們的需求是點擊Gitee登錄鏈接,會跳轉(zhuǎn)至一個第三方的登錄頁面,就像這樣:
那么該如何實現(xiàn)呢?
回到Gitee中,在創(chuàng)建完應(yīng)用后,將頁面拖動到下方,會看到模擬請求按鈕:
點擊一下該按鈕,會進行一個模擬登錄:
地址欄中的地址就是我們需要跳轉(zhuǎn)的頁面,將地址復制下來:
里面總共有3個參數(shù),分別是:
- client_id
- redirect_uri
- response_type
其中client_id在創(chuàng)建完應(yīng)用之后便會提供給我們:
也就是地址上的內(nèi)容,而redirect_uri是在點擊了同意授權(quán)按鈕之后需要跳轉(zhuǎn)的頁面,即:登錄成功之后,需要跳轉(zhuǎn)至成功后的頁面,最后是response_type,它表示響應(yīng)類型為一個授權(quán)碼。
來了解一下授權(quán)碼的作用,當用戶點擊了同意授權(quán)按鈕之后,Gitee服務(wù)器會給redirect_uri指向的頁面?zhèn)鬟f一個授權(quán)碼,此時就可以接收到這個授權(quán)碼,再去換取AccessToken,只有獲取到了AccessToken,才能夠獲取到Gitee中當前用戶的某些信息。
點擊了同意授權(quán)按鈕后:
得到了授權(quán)碼后,通過該地址能夠換取AccessToken:
https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}
該地址要求以Post形式請求,使用PostMan測試一下,將參數(shù)按要求設(shè)置好:
得到相應(yīng)結(jié)果:
{ "access_token": "cd2c33c3fe548a23188159f87da70110", "token_type": "bearer", "expires_in": 86400, "refresh_token": "c95a38ab2357638ffc4dc6f09c623f2333e0930a37dec8e2f191a40d7afd3514", "scope": "user_info", "created_at": 1627974370 }
得到了AccessToken之后,就可以獲取到用戶在Gitee中已經(jīng)授權(quán)的任何信息了。
整個授權(quán)認證的過程如下圖所示:
實現(xiàn)登錄流程
熟悉了整合流程之后,我們用代碼來實現(xiàn)一下,首先修改頁面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form> 用戶名:<input type="text"/><br/> 密碼:<input type="password"/><br/> <a >Gitee登錄</a> <input type="submit" value="登錄"/><br/> </form> </body> </html>
現(xiàn)在超鏈接的地址經(jīng)過修改后就能成功跳轉(zhuǎn)至Gitee授權(quán)頁面了,因為授權(quán)成功后跳轉(zhuǎn)的地址為 http://localhost:8080/success
,所以需要來處理一下這個請求,創(chuàng)建一個控制器:
@Controller public class LoginController { @GetMapping("/success") public String login(@RequestParam("code") String code){ System.out.println(code); return "success"; } @GetMapping("/") public String index(){ return "index"; } }
當授權(quán)成功后我們讓其跳轉(zhuǎn)至success.html頁面,并接收Gitee傳遞過來的授權(quán)碼,所以創(chuàng)建success.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>登錄成功!</h1> </body> </html>
啟動項目測試一下:
點擊同意授權(quán)后確實登錄成功了,控制臺也輸出了授權(quán)碼:
e907fd92d8392ebcd72dff321da45115ff0fba2dec0e6918b233ec7d03b76e5d
其實到這里登錄流程還沒有結(jié)束,因為如果使用第三方應(yīng)用登錄的話,平臺會使用第三方應(yīng)用的一些信息,比如賬號、頭像等直接作為當前平臺的登錄名和頭像,所以我們還需要獲取用戶在Gitee中的一些信息。
此處參考Gitee的API文檔:
比如獲取授權(quán)用戶的資料信息:
它需要傳遞一個access_token作為參數(shù),那我們要做的就是使用授權(quán)碼去得到access_key:
@Controller public class LoginController { @GetMapping("/success") public String login(@RequestParam("code") String code, Map<String,String> map) { // 獲取accesskey String accessKey = getAccessKey(code); System.out.println(accessKey); // 通過accessKey獲取用戶信息 String userInfo = getUserInfo(accessKey); // 取出用戶名 String name = (String) JSONObject.parseObject(userInfo).get("name"); // 取出頭像 String avatar_url = (String) JSONObject.parseObject(userInfo).get("avatar_url"); // 放入請求域 map.put("name",name); map.put("avatar_url",avatar_url); return "success"; } /** * 獲取用戶信息 */ private String getUserInfo(String accessKey) { String json = ""; OkHttpClient client = new OkHttpClient(); // 通過該地址能夠獲取到用戶信息 String url = "https://gitee.com/api/v5/user?access_token=" + accessKey; Request request = new Request.Builder() .get() .url(url).build(); try { Response response = client.newCall(request).execute(); json = response.body().string(); } catch (IOException e) { e.printStackTrace(); } return json; } /** * 獲取AccessKey */ private String getAccessKey(String code) { OkHttpClient client = new OkHttpClient(); // 通過該地址能夠獲取到access_token String url = "https://gitee.com/oauth/token"; // 封裝請求參數(shù) RequestBody requestBody = new FormBody.Builder() .add("grant_type", "authorization_code") .add("code", code) .add("client_id", "52908197466cd3008db76a6018de66c8d222656056fa78b26dd58d1f4fa0a606") .add("redirect_uri", "http://localhost:8080/success") .add("client_secret", "7e84401a9752e88d22d5450c1687ca6a19bc34f45fe3452cefd33312d8153978") .build(); Request request = new Request.Builder() .post(requestBody) .url(url).build(); String accessKey = ""; try { Response response = client.newCall(request).execute(); String json = response.body().string(); // 獲取json串中的access_token屬性 accessKey = (String) JSONObject.parseObject(json).get("access_token"); } catch (IOException e) { e.printStackTrace(); } return accessKey; } @GetMapping("/") public String index() { return "index"; } }
success.html頁面需要顯示用戶信息:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>登錄成功!</h1> <h1>用戶名:<span th:text="${#request.getAttribute('name')}"></span></h1> <img th:src="${#request.getAttribute('avatar_url')}"> </body> </html>
效果如下:
事實上,登錄流程遠沒有這么簡單,當用戶取消授權(quán)時就不能讓其登錄,程序里還沒有加上這類判斷,對于從未注冊過的用戶來說,這次登錄就相當于一次注冊,所以還需要以Gitee中用戶的某些信息作為注冊信息進行登錄,當已經(jīng)注冊過的用戶使用第三方登錄時,要讓其正常登錄。
到此這篇關(guān)于手把手教你實現(xiàn)Java第三方應(yīng)用登錄的文章就介紹到這了,更多相關(guān)Java第三方應(yīng)用登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java日期操作方法工具類實例【包含日期比較大小,相加減,判斷,驗證,獲取年份等】
這篇文章主要介紹了Java日期操作方法工具類,結(jié)合完整實例形式分析了java針對日期的各種常見操作,包括日期比較大小,相加減,判斷,驗證,獲取年份、天數(shù)、星期等,需要的朋友可以參考下2017-11-11Java使用Statement接口執(zhí)行SQL語句操作實例分析
這篇文章主要介紹了Java使用Statement接口執(zhí)行SQL語句操作,結(jié)合實例形式詳細分析了Java使用Statement接口針對mysql數(shù)據(jù)庫進行連接與執(zhí)行SQL語句增刪改查等相關(guān)操作技巧與注意事項,需要的朋友可以參考下2018-07-07基于spring AOP @Around @Before @After的區(qū)別說明
這篇文章主要介紹了基于spring AOP @Around @Before @After的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02Java的接口調(diào)用時的權(quán)限驗證功能的實現(xiàn)
這篇文章主要介紹了Java的接口調(diào)用時的權(quán)限驗證功能的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11