手把手教你實(shí)現(xiàn)Java第三方應(yīng)用登錄
大家在自己做項(xiàng)目的時(shí)候有沒(méi)有想過(guò)實(shí)現(xiàn)一個(gè)第三方應(yīng)用登錄呢?類(lèi)似這種:

本篇文章就來(lái)聊一聊該如何實(shí)現(xiàn)第三方應(yīng)用登錄。
什么是OAuth2.0
OAuth是一項(xiàng)協(xié)議,它為用戶(hù)資源的授權(quán)提供了一個(gè)安全、開(kāi)放而簡(jiǎn)易的標(biāo)準(zhǔn),OAuth的授權(quán)不會(huì)使第三方觸及到用戶(hù)的賬號(hào)信息(比如密碼),因此OAuth是相對(duì)安全的。而OAuth2.0就是OAuth的延續(xù),不過(guò)2.0更加關(guān)注客戶(hù)端開(kāi)發(fā)者的簡(jiǎn)易性。
申請(qǐng)網(wǎng)站接入
常見(jiàn)的第三方應(yīng)用都支持第三方登錄,比如:QQ、微信、微博、GitHub、Gitee等,要想申請(qǐng)第三方登錄權(quán)限,就需要去到對(duì)應(yīng)的平臺(tái),比如QQ,搜索QQ開(kāi)放平臺(tái):

進(jìn)入應(yīng)用管理,并創(chuàng)建應(yīng)用即可:

不過(guò)對(duì)于QQ、微信、微博等的網(wǎng)站接入都需要身份認(rèn)證,過(guò)程比較繁瑣,所以我們使用Gitee作為第三方應(yīng)用進(jìn)行接入。
首先打開(kāi)Gitee,選擇設(shè)置:

在設(shè)置中選擇第三方應(yīng)用:

點(diǎn)擊創(chuàng)建應(yīng)用并填寫(xiě)相關(guān)信息:

應(yīng)用名稱(chēng)可以隨意填寫(xiě),但是下面的兩個(gè)地址就有用途了,對(duì)于應(yīng)用主頁(yè),它需要填寫(xiě)的是當(dāng)前應(yīng)用的主頁(yè),而應(yīng)用回調(diào)接口填寫(xiě)的是當(dāng)?shù)卿洺晒笮枰D(zhuǎn)的頁(yè)面。
創(chuàng)建SpringBoot應(yīng)用
申請(qǐng)完成后,就可以來(lái)創(chuàng)建SpringBoot應(yīng)用,并新建一個(gè)index.html頁(yè)面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form>
用戶(hù)名:<input type="text"/><br/>
密碼:<input type="password"/><br/>
<a href="">Gitee登錄</a>
<input type="submit" value="登錄"/><br/>
</form>
</body>
</html>
效果如下:

頁(yè)面很丑,但不重要,實(shí)現(xiàn)功能即可。
現(xiàn)在我們的需求是點(diǎn)擊Gitee登錄鏈接,會(huì)跳轉(zhuǎn)至一個(gè)第三方的登錄頁(yè)面,就像這樣:

那么該如何實(shí)現(xiàn)呢?
回到Gitee中,在創(chuàng)建完應(yīng)用后,將頁(yè)面拖動(dòng)到下方,會(huì)看到模擬請(qǐng)求按鈕:

點(diǎn)擊一下該按鈕,會(huì)進(jìn)行一個(gè)模擬登錄:

地址欄中的地址就是我們需要跳轉(zhuǎn)的頁(yè)面,將地址復(fù)制下來(lái):
里面總共有3個(gè)參數(shù),分別是:
- client_id
- redirect_uri
- response_type
其中client_id在創(chuàng)建完應(yīng)用之后便會(huì)提供給我們:

也就是地址上的內(nèi)容,而redirect_uri是在點(diǎn)擊了同意授權(quán)按鈕之后需要跳轉(zhuǎn)的頁(yè)面,即:登錄成功之后,需要跳轉(zhuǎn)至成功后的頁(yè)面,最后是response_type,它表示響應(yīng)類(lèi)型為一個(gè)授權(quán)碼。
來(lái)了解一下授權(quán)碼的作用,當(dāng)用戶(hù)點(diǎn)擊了同意授權(quán)按鈕之后,Gitee服務(wù)器會(huì)給redirect_uri指向的頁(yè)面?zhèn)鬟f一個(gè)授權(quán)碼,此時(shí)就可以接收到這個(gè)授權(quán)碼,再去換取AccessToken,只有獲取到了AccessToken,才能夠獲取到Gitee中當(dāng)前用戶(hù)的某些信息。
點(diǎn)擊了同意授權(quán)按鈕后:

得到了授權(quán)碼后,通過(guò)該地址能夠換取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形式請(qǐng)求,使用PostMan測(cè)試一下,將參數(shù)按要求設(shè)置好:

得到相應(yīng)結(jié)果:
{
"access_token": "cd2c33c3fe548a23188159f87da70110",
"token_type": "bearer",
"expires_in": 86400,
"refresh_token": "c95a38ab2357638ffc4dc6f09c623f2333e0930a37dec8e2f191a40d7afd3514",
"scope": "user_info",
"created_at": 1627974370
}
得到了AccessToken之后,就可以獲取到用戶(hù)在Gitee中已經(jīng)授權(quán)的任何信息了。
整個(gè)授權(quán)認(rèn)證的過(guò)程如下圖所示:

實(shí)現(xiàn)登錄流程
熟悉了整合流程之后,我們用代碼來(lái)實(shí)現(xiàn)一下,首先修改頁(yè)面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form>
用戶(hù)名:<input type="text"/><br/>
密碼:<input type="password"/><br/>
<a >Gitee登錄</a>
<input type="submit" value="登錄"/><br/>
</form>
</body>
</html>
現(xiàn)在超鏈接的地址經(jīng)過(guò)修改后就能成功跳轉(zhuǎn)至Gitee授權(quán)頁(yè)面了,因?yàn)槭跈?quán)成功后跳轉(zhuǎn)的地址為 http://localhost:8080/success ,所以需要來(lái)處理一下這個(gè)請(qǐng)求,創(chuàng)建一個(gè)控制器:
@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";
}
}
當(dāng)授權(quán)成功后我們讓其跳轉(zhuǎn)至success.html頁(yè)面,并接收Gitee傳遞過(guò)來(lái)的授權(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>
啟動(dòng)項(xiàng)目測(cè)試一下:

點(diǎn)擊同意授權(quán)后確實(shí)登錄成功了,控制臺(tái)也輸出了授權(quán)碼:
e907fd92d8392ebcd72dff321da45115ff0fba2dec0e6918b233ec7d03b76e5d
其實(shí)到這里登錄流程還沒(méi)有結(jié)束,因?yàn)槿绻褂玫谌綉?yīng)用登錄的話,平臺(tái)會(huì)使用第三方應(yīng)用的一些信息,比如賬號(hào)、頭像等直接作為當(dāng)前平臺(tái)的登錄名和頭像,所以我們還需要獲取用戶(hù)在Gitee中的一些信息。
此處參考Gitee的API文檔:

比如獲取授權(quán)用戶(hù)的資料信息:

它需要傳遞一個(gè)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);
// 通過(guò)accessKey獲取用戶(hù)信息
String userInfo = getUserInfo(accessKey);
// 取出用戶(hù)名
String name = (String) JSONObject.parseObject(userInfo).get("name");
// 取出頭像
String avatar_url = (String) JSONObject.parseObject(userInfo).get("avatar_url");
// 放入請(qǐng)求域
map.put("name",name);
map.put("avatar_url",avatar_url);
return "success";
}
/**
* 獲取用戶(hù)信息
*/
private String getUserInfo(String accessKey) {
String json = "";
OkHttpClient client = new OkHttpClient();
// 通過(guò)該地址能夠獲取到用戶(hù)信息
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();
// 通過(guò)該地址能夠獲取到access_token
String url = "https://gitee.com/oauth/token";
// 封裝請(qǐng)求參數(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頁(yè)面需要顯示用戶(hù)信息:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>登錄成功!</h1>
<h1>用戶(hù)名:<span th:text="${#request.getAttribute('name')}"></span></h1>
<img th:src="${#request.getAttribute('avatar_url')}">
</body>
</html>
效果如下:

事實(shí)上,登錄流程遠(yuǎn)沒(méi)有這么簡(jiǎn)單,當(dāng)用戶(hù)取消授權(quán)時(shí)就不能讓其登錄,程序里還沒(méi)有加上這類(lèi)判斷,對(duì)于從未注冊(cè)過(guò)的用戶(hù)來(lái)說(shuō),這次登錄就相當(dāng)于一次注冊(cè),所以還需要以Gitee中用戶(hù)的某些信息作為注冊(cè)信息進(jìn)行登錄,當(dāng)已經(jīng)注冊(cè)過(guò)的用戶(hù)使用第三方登錄時(shí),要讓其正常登錄。
到此這篇關(guān)于手把手教你實(shí)現(xiàn)Java第三方應(yīng)用登錄的文章就介紹到這了,更多相關(guān)Java第三方應(yīng)用登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis下動(dòng)態(tài)sql中##和$$的區(qū)別講解
今天小編就為大家分享一篇關(guān)于Mybatis下動(dòng)態(tài)sql中##和$$的區(qū)別講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
springboot實(shí)現(xiàn)極驗(yàn)校驗(yàn)的項(xiàng)目實(shí)踐
在系統(tǒng)業(yè)務(wù)中,需要想客戶(hù)發(fā)送手機(jī)驗(yàn)證碼,進(jìn)行驗(yàn)證后,才能提交,本文主要介紹了springboot實(shí)現(xiàn)極驗(yàn)校驗(yàn)的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
JAVA基于數(shù)組實(shí)現(xiàn)的商品信息查詢(xún)功能示例
這篇文章主要介紹了JAVA基于數(shù)組實(shí)現(xiàn)的商品信息查詢(xún)功能,結(jié)合實(shí)例形式詳細(xì)分析了java使用數(shù)組存儲(chǔ)數(shù)據(jù)實(shí)現(xiàn)的商品信息查詢(xún)功能相關(guān)操作技巧,需要的朋友可以參考下2019-11-11
Spring Cloud Config分布式配置中心使用介紹詳解
分布式配置中心應(yīng)用場(chǎng)景 往往,我們使用配置文件管理?些配置信息,比如application.yml 單體應(yīng)用架構(gòu):配置信息的管理、維護(hù)并不會(huì)顯得特別麻煩,手動(dòng)操作就可以,因?yàn)榫鸵粋€(gè)工程2022-09-09
解析如何開(kāi)發(fā)FineReport的自定義控件
FineReport作為插件化開(kāi)發(fā)的報(bào)表軟件,有些特殊需求的功能需要自己開(kāi)發(fā),開(kāi)發(fā)的插件包帆軟官方有提提供,可以去帆軟論壇上找,本文將主要介紹如何開(kāi)發(fā)一個(gè)自定義控件,這里講講方法論。需要的朋友一起來(lái)看下吧2016-12-12
Java裝飾器設(shè)計(jì)模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java裝飾器設(shè)計(jì)模式的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05
Springboot集成JSR303參數(shù)校驗(yàn)的方法實(shí)現(xiàn)
這篇文章主要介紹了Springboot集成JSR303參數(shù)校驗(yàn)的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
java中extends與implements的區(qū)別淺談
java中extends與implements的區(qū)別淺談,需要的朋友可以參考一下2013-03-03
Nacos源碼之注冊(cè)中心的實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Nacos源碼之注冊(cè)中心的實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
解決idea不支持SpringBoot yml文件的圖文教程
這篇文章主要介紹了解決idea不支持SpringBoot yml文件,需要的朋友可以參考下2018-06-06

