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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

从零玩转第三方登录之QQ登录

發布時間:2023/12/14 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从零玩转第三方登录之QQ登录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

從零玩轉第三方登錄之QQ登錄

前言

在真正開始對接之前,我們先來聊一聊后臺的方案設計。既然是對接第三方登錄,那就免不了如何將用戶信息保存。首先需要明確一點的是,用戶在第三方登錄成功之后,
我們能拿到的僅僅是一個代表用戶唯一身份的ID(微博是真實uid,QQ是加密的openID)以及用來識別身份的accessToken,當然還有昵稱、頭像、性別等有限資料,
對接第三方登錄的關鍵就是如何確定用戶是合法登錄,如果確定這次登錄的和上次登錄的是同一個人并且不是假冒的。其實這個并不用我們特別操心,就以微博登錄為例,
用戶登錄成功之后會回調一個code給我們,然后我們再拿code去微博那換取 accessToken ,如果這個code是用戶亂填的,那這一關肯定過不了,所以,前面的擔心有點多余,哈哈。

1. 認識Oauth2.0

現在很多網站都要不管是為了引流也好,為了用戶方便也好一般都有第三方賬號登陸的需求,今天以QQ登陸為例,來實現一個最簡單的第三方登陸。
目前主流的第三方登錄都是依賴的Oauth2.0實現的,最常見的就是在各種中小型網站或者App中的QQ登錄,微信登錄等等。所以我建議想要學習和實現第三方登錄同學去了解下這個協議。

必須要域名并且進行備案

比如我的域名: https://yangbuyi.top/
因為騰訊有一個域名認證機制啥的。。。。。。

2.實名認證
QQ登錄我們對接的是QQ互聯,地址:https://connect.qq.com ,首先需要注冊成為開發者并實名認證,需要手持身份證照片,具體就不講了。

2.1、進行申請開發者身份

2.2 創建應用

進入應用管理頁面創建應用,根據實際需要是創建網站應用還是移動應用,我這里是網站應用:

提交成功完步后等待客服審核即可

這是我網站的基本接口信息

QQ登陸流程

請求參數

創建springboot工程

依賴

<!-- qq登陸集成 開始 --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.11</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.8</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpasyncclient</artifactId></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId></dependency><!--json轉換工具--><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency><!--QQSDK--><dependency><groupId>net.gplatform</groupId><artifactId>Sdk4J</artifactId><version>2.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.62</version></dependency><!-- qq登陸集成 結束 --><!-- 模板 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- 其它配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>

創建http請求工具

import com.alibaba.fastjson.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory;import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import java.security.GeneralSecurityException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors;/*** description: 楊不易網站 :www.yangbuyi.top* ClassName: HttpsUtils* create: 2020-06-24 17:30** @author: yangbuyi* @since: JDK1.8**/public class HttpsUtils {private static PoolingHttpClientConnectionManager connMgr;private static RequestConfig requestConfig;private static final int MAX_TIMEOUT = 7000;private static final Logger logger = LoggerFactory.getLogger(HttpsUtils.class);static {// 設置連接池connMgr = new PoolingHttpClientConnectionManager();// 設置連接池大小connMgr.setMaxTotal(100);connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());// Validate connections after 1 sec of inactivityconnMgr.setValidateAfterInactivity(1000);RequestConfig.Builder configBuilder = RequestConfig.custom();// 設置連接超時configBuilder.setConnectTimeout(MAX_TIMEOUT);// 設置讀取超時configBuilder.setSocketTimeout(MAX_TIMEOUT);// 設置從連接池獲取連接實例的超時configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);requestConfig = configBuilder.build();}/*** 發送 GET 請求(HTTP),不帶輸入數據** @param url* @return*/public static String doGet(String url) {return doGet(url, new HashMap<String, Object>());}/*** 發送 GET 請求(HTTP),K-V形式** @param url* @param params* @return*/public static String doGet(String url, Map<String, Object> params) {String apiUrl = url;StringBuffer param = new StringBuffer();int i = 0;for (String key : params.keySet()) {if (i == 0)param.append("?");elseparam.append("&");param.append(key).append("=").append(params.get(key));i++;}apiUrl += param;String result = null;HttpClient httpClient = null;if (apiUrl.startsWith("https")) {httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();} else {httpClient = HttpClients.createDefault();}try {HttpGet httpGet = new HttpGet(apiUrl);HttpResponse response = httpClient.execute(httpGet);HttpEntity entity = response.getEntity();if (entity != null) {InputStream instream = entity.getContent();result = new BufferedReader(new InputStreamReader(instream)).lines().collect(Collectors.joining(System.lineSeparator()));}} catch (IOException e) {logger.error(e.getMessage());}return result;}/*** 發送 POST 請求(HTTP),不帶輸入數據** @param apiUrl* @return*/public static String doPost(String apiUrl) {return doPost(apiUrl, new HashMap<String, Object>());}/*** 發送 POST 請求,K-V形式** @param apiUrl API接口URL* @param params 參數map* @return*/public static String doPost(String apiUrl, Map<String, Object> params) {CloseableHttpClient httpClient = null;if (apiUrl.startsWith("https")) {httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();} else {httpClient = HttpClients.createDefault();}String httpStr = null;HttpPost httpPost = new HttpPost(apiUrl);CloseableHttpResponse response = null;try {httpPost.setConfig(requestConfig);List<NameValuePair> pairList = new ArrayList<>(params.size());for (Map.Entry<String, Object> entry : params.entrySet()) {NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());pairList.add(pair);}httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));response = httpClient.execute(httpPost);HttpEntity entity = response.getEntity();httpStr = EntityUtils.toString(entity, "UTF-8");} catch (IOException e) {logger.error(e.getMessage());} finally {if (response != null) {try {EntityUtils.consume(response.getEntity());} catch (IOException e) {logger.error(e.getMessage());}}}return httpStr;}/*** 發送 POST 請求,JSON形式** @param apiUrl* @param json json對象* @return*/public static String doPost(String apiUrl, Object json) {CloseableHttpClient httpClient = null;if (apiUrl.startsWith("https")) {httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();} else {httpClient = HttpClients.createDefault();}String httpStr = null;HttpPost httpPost = new HttpPost(apiUrl);CloseableHttpResponse response = null;try {httpPost.setConfig(requestConfig);StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解決中文亂碼問題stringEntity.setContentEncoding("UTF-8");stringEntity.setContentType("application/json");httpPost.setEntity(stringEntity);response = httpClient.execute(httpPost);HttpEntity entity = response.getEntity();httpStr = EntityUtils.toString(entity, "UTF-8");} catch (IOException e) {logger.error(e.getMessage());} finally {if (response != null) {try {EntityUtils.consume(response.getEntity());} catch (IOException e) {logger.error(e.getMessage());}}}return httpStr;}/*** 創建SSL安全連接** @return*/private static SSLConnectionSocketFactory createSSLConnSocketFactory() {SSLConnectionSocketFactory sslsf = null;try {SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {@Overridepublic boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {return true;}}).build();sslsf = new SSLConnectionSocketFactory(sslContext, new HostnameVerifier() {@Overridepublic boolean verify(String arg0, SSLSession arg1) {return true;}});} catch (GeneralSecurityException e) {logger.error(e.getMessage());}return sslsf;}/*gitHub開始*//*** 發送get請求,利用java代碼發送請求* @param url* @return* @throws Exception*/public static String doGetHub(String url) throws Exception{CloseableHttpClient httpclient = HttpClients.createDefault();HttpGet httpGet = new HttpGet(url);// 發送了一個http請求CloseableHttpResponse response = httpclient.execute(httpGet);// 如果響應200成功,解析響應結果if(response.getStatusLine().getStatusCode()==200){// 獲取響應的內容HttpEntity responseEntity = response.getEntity();return EntityUtils.toString(responseEntity);}return null;}/*** 將字符串轉換成map* @param responseEntity* @return*/public static Map<String,String> getMap(String responseEntity) {Map<String, String> map = new HashMap<>();// 以&來解析字符串String[] result = responseEntity.split("\\&");for (String str : result) {// 以=來解析字符串String[] split = str.split("=");// 將字符串存入map中if (split.length == 1) {map.put(split[0], null);} else {map.put(split[0], split[1]);}}return map;}/*** 通過json獲得map* @param responseEntity* @return*/public static Map<String,String> getMapByJson(String responseEntity) {Map<String, String> map = new HashMap<>();// 阿里巴巴fastjson 將json轉換成mapJSONObject jsonObject = JSONObject.parseObject(responseEntity);for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {String key = entry.getKey();// 將obj轉換成stringString value = String.valueOf(entry.getValue()) ;map.put(key, value);}return map;}/*gitHub結束*/}

創建跨域配置類 以防萬一出現跨域問題

import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter;/*** ClassName: CorsAutoConfig** @author yangshuai* @Date: 2021-04-13 14:54* @Description: $**/ @Configuration public class CorsAutoConfig {@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");// 表示什么域名跨域 *表示全部都跨域corsConfiguration.addAllowedOrigin("*");// 注入進去urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);CorsFilter corsFilter = new CorsFilter(urlBasedCorsConfigurationSource);return corsFilter;} }

創建Logincontroller

import com.google.gson.Gson; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import top.yangbuyi.QQ.OAuthProperties; import top.yangbuyi.QQ.vo.QQDTO; import top.yangbuyi.QQ.vo.QQOpenidDTO; import top.yangbuyi.common.HttpsUtils;import javax.management.RuntimeErrorException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.websocket.server.PathParam; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID;/*** @description: 楊不易網站:www.yangbuyi.top* @program: qqlogindemo* @ClassName: loginController* @create: 2020-08-18 14:41* @author: yangbuyi* @since: JDK1.8* @loginController: 第三方QQ登陸**/@Controller @Slf4j @RequestMapping("api") public class loginController {/*** 認證參數*/@Autowiredprivate OAuthProperties oauth;/*** 調用QQ登陸接口* 流程: 先調用接口獲取code,在根據code獲取access_token,在根據token獲取對應的用戶信息* @param response*/@GetMapping("/login/oauth")public void loginQQ( HttpServletResponse response) {// 重定向訪問QQ登錄服務器try {response.sendRedirect(oauth.getQQ().getCode_callback_uri() + //獲取code碼地址"?client_id=" + oauth.getQQ().getClient_id() //appid+"&state=" + UUID.randomUUID() + //這個說是防攻擊的,就給個隨機uuid吧"&redirect_uri=" + oauth.getQQ().getRedirect_uri() +//這個很重要,這個是回調地址,即就收騰訊返回的code碼"&response_type=code");} catch (IOException e) {e.printStackTrace();}}/*** 在qq平臺設置的回調地址** 接收回調地址帶過來的code碼** @param code* @param request* @return*/@GetMapping("/oauth2")public String authorizeQQ(String code, HttpServletRequest request) {HashMap<String, Object> params = new HashMap<>();params.put("code", code);params.put("grant_type", "authorization_code");params.put("redirect_uri", oauth.getQQ().getRedirect_uri());params.put("client_id", oauth.getQQ().getClient_id());params.put("client_secret", oauth.getQQ().getClient_secret());// 獲取騰訊access tokenMap<String, String> reulsts = getAccess_token(params);System.out.println("遍歷拿到的數據:");for (Map.Entry<String, String> entry : reulsts.entrySet()) {System.out.println(entry.getKey() + "=" + entry.getValue());}System.out.println("遍歷完畢");//到這里access_token已經處理好了//下一步獲取openid,只有拿到openid才能拿到用戶信息String openidContent = HttpsUtils.doGet(oauth.getQQ().getOpenid_callback_uri() + "?access_token=" + reulsts.get("access_token"));// callback( {"client_id":"101887062","openid":"74DD1353321FD56375F34422D833848D"} );System.out.println("openidContent: " + openidContent);//接下來對openid進行處理//截取需要的那部分json字符串String openid = openidContent.substring(openidContent.indexOf("{"), openidContent.indexOf("}") + 1);// json 轉 對象Gson gson = new Gson();//將返回的openid轉換成DTOQQOpenidDTO qqOpenidDTO = gson.fromJson(openid, QQOpenidDTO.class);// 封裝參數 請求用戶信息數據params.clear();//設置access_tokenparams.put("access_token", reulsts.get("access_token"));//設置openidparams.put("openid", qqOpenidDTO.getOpenid());//設置appidparams.put("oauth_consumer_key", qqOpenidDTO.getClient_id());//獲取用戶信息String userInfo = HttpsUtils.doGet(oauth.getQQ().getUser_info_callback_uri(), params);QQDTO qqDTO = gson.fromJson(userInfo, QQDTO.class);// (正常情況下,在開發時候用openid作為用戶名,再自己定義個密碼就可以了)try {/* 組裝數據 */HashMap<String, Object> map = new HashMap<>();map.put("user", qqDTO);map.put("qqOpenidDTO", qqOpenidDTO);request.setAttribute("map", map);log.info("user數據:{}" + qqDTO);log.info("qqOpenidDTO數據:{}" + qqOpenidDTO);return "home";} catch (Exception e) {e.printStackTrace();return "login";}}/*** 獲取騰訊 access_token** @return*/public Map<String, String> getAccess_token(HashMap<String, Object> params) {// 認證地址//獲取access_token如:access_token=9724892714FDF1E3ED5A4C6D074AF9CB&expires_in=7776000&refresh_token=9E0DE422742ACCAB629A54B3BFEC61FFString result = HttpsUtils.doGet(oauth.getQQ().getAccess_token_callback_uri(), params);//對拿到的數據進行切割字符串String[] strings = result.split("&");//切割好后放進mapMap<String, String> reulsts = new HashMap<>();for (String str : strings) {String[] split = str.split("=");if (split.length > 1) {reulsts.put(split[0], split[1]);}}return reulsts;}}

創建QQ參數實體類

創建 OAuthProperties 用于配合yml配置文件動態獲取參數

import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;/*** description: 楊不易網站 :www.yangbuyi.top* ClassName: OAuthProperties* create: 2020-06-24 17:06** @author: yangbuyi* @since: JDK1.8* <p>* 獲取Code碼**/@Component //對應application.yml中,oauth下參數 @ConfigurationProperties(prefix = "oauth") public class OAuthProperties {//獲取applicaiton.yml下qq下所有的參數private QQProperties qq = new QQProperties();public QQProperties getQQ() {return qq;}public void setQQ(QQProperties qq) {this.qq = qq;} }

創建 QQProperties 用于請求qq的參數

import lombok.Data; import org.springframework.stereotype.Component;/*** description: 楊不易網站 :www.yangbuyi.top* ClassName: QQProperties* create: 2020-06-24 17:04** @author: yangbuyi* @since: JDK1.8** 集成第三方登陸 QQ 參數**/ @Data @Component public class QQProperties {/*** 你的appid*/private String client_id;/*** #你的appkey*/private String client_secret;/*** 你接收響應code碼地址*/private String redirect_uri;/*** 騰訊獲取code碼地址*/private String code_callback_uri;/*** 騰訊獲取access_token地址*/private String access_token_callback_uri;/*** 騰訊獲取openid地址*/private String openid_callback_uri;/*** 騰訊獲取用戶信息地址*/private String user_info_callback_uri;/*** 要回調到哪個網站*/private String redirect_url_index_yby;private String redirect_url_login_yby;}

創建 QQOpenidDTO 用于獲取 access_token、openid

import lombok.Data;/*** description: 楊不易網站 :www.yangbuyi.top* ClassName: QQOpenidDTO* create: 2020-06-24 17:19** @author: yangbuyi* @since: JDK1.8** 用來獲取 access_token、openid**/ @Datapublic class QQOpenidDTO {private String openid;private String client_id;}

創建QQDTO 接收QQ返回來的json參數

import lombok.Data;/*** description: 楊不易網站 :www.yangbuyi.top* program: yangbuyi-erp-2020* ClassName: QQDTO* create: 2020-06-24 17:20** @author: yangbuyi* @since: JDK1.8* @QQDTO: 用于存儲QQ服務器返回來的參數**/@Data public class QQDTO {private String ret; //返回碼private String msg; //如果ret<0,會有相應的錯誤信息提示,返回數據全部用UTF-8編碼。private String nickname; //用戶在QQ空間的昵稱。private String figureurl; //大小為30×30像素的QQ空間頭像URL。private String figureurl_1; //大小為50×50像素的QQ空間頭像URL。private String figureurl_2; //大小為100×100像素的QQ空間頭像URL。private String figureurl_qq_1; //大小為40×40像素的QQ頭像URL。private String figureurl_qq_2; //大小為100×100像素的QQ頭像URL。需要注意,不是所有的用戶都擁有QQ的100x100的頭像,但40x40像素則是一定會有。private String gender; //性別。 如果獲取不到則默認返回"男"private Integer gendertype; // 性別 數字private String is_yellow_vip; //標識用戶是否為黃鉆用戶(0:不是;1:是)。private String vip; //標識用戶是否為黃鉆用戶(0:不是;1:是)private String yellow_vip_level; //黃鉆等級private String level; //黃鉆等級private String is_yellow_year_vip; //標識是否為年費黃鉆用戶(0:不是; 1:是)private String province; // 省private String city; // 市 }

示例

創建前端請求跳轉 controller

@Controller @Slf4j public class RequestController {@RequestMapping("login")public String login() {System.out.println("登陸進來啦");return "login";}@RequestMapping("home")public String home() {return "home";}}

創建前端頁面

login.html

<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <!--登錄地址 action="/api/login/oauth" --> <form action="/api/login/oauth"><input type="submit" style="background: red;size: 25px" value="登陸"> </form> </body> </html>

home.html

<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <div class=""><label class="">登陸成功</label><div class=""><p th:text="'openID :' + ${map.qqOpenidDTO.openid}"></p><p th:text="'用戶名稱 :' + ${map.user.nickname}"></p>用戶頭像:<img th:src="${map.user.figureurl_qq_1}" alt=""><br><img th:src="${map.user.figureurl_qq_1}" alt=""><img th:src="${map.user.figureurl_qq_2}" alt="">性別:<p th:text="${map.user.gender}"></p><p th:text="${map.user.vip}"></p><p th:text="${map.user.yellow_vip_level}"></p><p th:text="${map.user.is_yellow_year_vip}"></p><p th:text="${map.user.province}"></p><p th:text="${map.user.city}"></p></div> </div><!--參數列表:--> <!--private String ret; //返回碼--> <!--private String msg; //如果ret<0,會有相應的錯誤信息提示,返回數據全部用UTF-8編碼。--> <!--private String nickname; //用戶在QQ空間的昵稱。--> <!--private String figureurl; //大小為30×30像素的QQ空間頭像URL。--> <!--private String figureurl_1; //大小為50×50像素的QQ空間頭像URL。--> <!--private String figureurl_2; //大小為100×100像素的QQ空間頭像URL。--> <!--private String figureurl_qq_1; //大小為40×40像素的QQ頭像URL。--> <!--private String figureurl_qq_2; //大小為100×100像素的QQ頭像URL。需要注意,不是所有的用戶都擁有QQ的100x100的頭像,但40x40像素則是一定會有。--> <!--private String gender; //性別。 如果獲取不到則默認返回"男"--> <!--private Integer gendertype; // 性別 數字--> <!--private String is_yellow_vip; //標識用戶是否為黃鉆用戶(0:不是;1:是)。--> <!--private String vip; //標識用戶是否為黃鉆用戶(0:不是;1:是)--> <!--private String yellow_vip_level; //黃鉆等級--> <!--private String level; //黃鉆等級--> <!--private String is_yellow_year_vip; //標識是否為年費黃鉆用戶(0:不是; 1:是)--> <!--private String province; // 省--> <!--private String city; // 市--></body> </html>

啟動注意事項

必須要打包到服務器啟動QQ才能回調

項目部署

方案一:

點擊package 打包

復制 項目 和 application.yml 上傳到linux服務器

修改application.yml 中的端口為 80

運行 Java程序

java -jar qqlogindemo-0.0.1-SNAPSHOT.jar

啟動成功

訪問 login 頁面

點擊登錄 》 QQ掃碼或者密碼登錄 》 登錄成功 跳轉到 home

方案二:

現在大部分都是 前后端分離一定使用nginx代理來進行轉發 我們使用nginx來進行
修改 application.yml 端口為 除 80 以外的端口 因為 80是nginx的默認端口

修改你服務器上的nginx.config 文件

# 監聽回調地址為api請求的 并且反向代理到 xxxx端口 即可location ^~/api {proxy_pass http://yangbuyi.top:xxxx;proxy_send_timeout 1800;proxy_read_timeout 1800;proxy_connect_timeout 1800;client_max_body_size 2048m;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}

刷新 nginx

重新啟動 Java程序 步驟就與 方案一 一致

到此 從零玩轉 第三方登錄之QQ登錄 就結束了哦。

GITEE:https://gitee.com/yangbuyi

GITHUB: https://github.com/GenuineYangShuai

個人博客網站: https://www.yangbuyi.top/

春天交流群 :598347590

🍺你的壓力源于無法自律,只是假裝努力,現狀跟不上你內心的欲望,所以你焦急又恐慌---楊不易.|

本文作者:楊不易呀

本文鏈接:https://www.yangbuyi.top/qqLogin

版權聲明:本作品采用知識共享署名-非商業性使用-禁止演繹 2.5 中國大陸許可協議進行許可。

總結

以上是生活随笔為你收集整理的从零玩转第三方登录之QQ登录的全部內容,希望文章能夠幫你解決所遇到的問題。

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