超贊!終于有網(wǎng)友用 Java 實(shí)現(xiàn)了第三方 QQ 賬號登錄。。。

來源 | uidaima.com/blog/4725615031700480.htm
QQ互聯(lián)注冊一個(gè)賬號 加入jar包 登錄頁面 Controller編寫 AuthComment類編寫 登錄成功跳轉(zhuǎn)到頁面 成功后的頁面index freemarker配置
QQ互聯(lián)注冊一個(gè)賬號
網(wǎng)站地址:https://connect.qq.com/,添加一個(gè)應(yīng)用,具體怎么申請以及需要填寫的信息,騰訊官網(wǎng)有詳細(xì)文檔。注冊并完成相應(yīng)信息填寫后,可以在應(yīng)用管理中查到應(yīng)用的APP ID和APP Key。(注,這個(gè)申請還是比較麻煩的,申請了好幾次,可能是臉黑吧)成功后如下圖:

還需要添加一個(gè)回調(diào)地址,如下圖:

加入jar包
????com.qq
????Sdk4J
????2
登錄頁面

Controller編寫
package?com.gbq.boot.web.controller;
import?cn.hutool.core.util.StrUtil;
import?com.alibaba.fastjson.JSONObject;
import?com.gbq.boot.web.bean.User;
import?com.gbq.boot.web.comment.qqLoginComment.AuthComment;
import?com.gbq.boot.web.service.UserService;
import?org.springframework.web.bind.annotation.*;
import?org.springframework.web.servlet.ModelAndView;
import?org.springframework.web.servlet.mvc.support.RedirectAttributes;
import?javax.annotation.Resource;
import?javax.servlet.http.HttpServletResponse;
/**
?*?登錄Controller
?*?@author?阿前
?*?2019年1月4日09:48:21
?*/
@RestController
@RequestMapping("/login")
public?class?LoginController?{
????@Resource
????private?UserService?userService;
????@Resource
????private?AuthComment?authComment;
????@RequestMapping("/index")
????public?ModelAndView?index(@ModelAttribute("user")?User?user)?{
????????return?new?ModelAndView("/shop/index","user",user);
????}
????@RequestMapping("/login.html")
????public?ModelAndView?toLogin()?{
????????return?new?ModelAndView("login");
????}
????@RequestMapping("/qqLogin")
????public?void?qqLogin(HttpServletResponse?response)throws?Exception{
????????//隨機(jī)產(chǎn)生字符串
????????String?state?=?StrUtil.uuid();
????????String?url?=?authComment.getAuthUrl(state);
????????System.out.println(url);
????????//重定向
????????response.sendRedirect(url);
????}
????@GetMapping("/redirect")
????public?ModelAndView?getData(@RequestParam(value?=?"code")?String?code,?RedirectAttributes?model){
????????//獲取token
????????String?accessToken?=?authComment.getAccessToken(code);
????????System.out.println("accessToken"+accessToken);
????????//獲取openId
????????String?openId?=?authComment.getOpenId(accessToken);
????????System.out.println("openId"+openId);
????????//獲取用戶信息
????????JSONObject?userInfo?=?authComment.getUserInfo(accessToken,?openId);
????????String?myName?=?userInfo.getString("nickname");
????????User?user?=?new?User(null,?"","111111",myName,?System.currentTimeMillis(),"是",
????????????????userInfo.getString("figureurl_2"),?userInfo.getString("gender")
????????????????,1,1,"",?"",?openId);
????????//通過openId查詢
????????User?usr?=?userService.findUsrByOpenId(openId);
????????if?(null?!=?usr){
????????????user.setId(usr.getId());
????????????userService.updateById(user);
????????}else?{
????????????userService.insert(user);
????????}
????????model.addFlashAttribute("user",?user);
???????//重定向
????????return?new?ModelAndView("redirect:/login/index");
????}
}
AuthComment類編寫
package?com.gbq.boot.web.comment.qqLoginComment;
import?com.alibaba.fastjson.JSON;
import?com.alibaba.fastjson.JSONObject;
import?org.springframework.stereotype.Component;
import?java.io.IOException;
import?java.io.InputStream;
import?java.net.HttpURLConnection;
import?java.net.URL;
import?java.util.regex.Matcher;
import?java.util.regex.Pattern;
import?static?org.apache.commons.io.IOUtils.toByteArray;
@Component
public?class?AuthComment?{
????//QQ?登陸頁面的URL
????private?final?static?String?AUTHORIZATION_URL?=
????????????"https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s";
????//獲取token的URL
????private?final?static?String?ACCESS_TOKEN_URL?=?"https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s";
????//?獲取用戶?openid?的?URL
????private?static?final?String?OPEN_ID_URL?=?"https://graph.qq.com/oauth2.0/me?access_token=%s";
????//?獲取用戶信息的?URL,oauth_consumer_key?為?apiKey
????private?static?final?String?USER_INFO_URL?=?"https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s";
????//?下面的屬性可以通過配置讀取
????//?QQ?在登陸成功后回調(diào)的?URL,這個(gè)?URL?必須在?QQ?互聯(lián)里填寫過
????private?static?final?String?CALLBACK_URL?=?"http://127.0.0.1:8080/login/redirect";
????//?QQ?互聯(lián)應(yīng)用管理中心的?APP?ID
????private?static?final?String?APP_ID?=?"你的id";
????//?QQ?互聯(lián)應(yīng)用管理中心的?APP?Key
????private?static?final?String?APP_SECRET?=?"你的key";
????/**
?????*?QQ?登陸頁面的URL
?????*?@param?scope
?????*?@return
?????*/
????public?String?getAuthUrl(String?scope)?{
????????return?String.format(AUTHORIZATION_URL,?APP_ID,?CALLBACK_URL,?scope);
????}
????/**
?????*?獲取Access?Token值
?????*/
????public?String?getAccessToken(String?code){
????????String?ur?=?String.format(ACCESS_TOKEN_URL,?APP_ID,?APP_SECRET,code,?CALLBACK_URL);
????????String?compile?=?"access_token=(\\w*)&";
????????String?result?=?this.getUrl(ur);
????????return?this.getMatcher(result,compile);
????}
????/**
?????*?獲取openId
?????*?@param?accessToken
?????*?@return
?????*/
????public?String?getOpenId(String?accessToken)?{
????????String?url?=?String.format(OPEN_ID_URL,?accessToken);
????????String?compile?=?"openid\":\"(\\w*)\"";
????????String?result?=?this.getUrl(url);
????????return?this.getMatcher(result,compile);
????}
????/**
?????*?獲取qq用戶信息
?????*?@param?accessToken
?????*?@param?openId
?????*?@return
?????*/
????public?JSONObject?getUserInfo(String?accessToken,?String?openId)?{
????????String?url?=?String.format(USER_INFO_URL,?accessToken,?APP_ID,?openId);
????????String?result?=?this.getUrl(url);
????????return?JSON.parseObject(result);
????}
????private?String?getMatcher(String?result,String?compile)?{
????????//使用正則表達(dá)式解析網(wǎng)址
????????Pattern?p?=?Pattern.compile(compile);
????????Matcher?m?=?p.matcher(result);
????????m.find();
????????return?m.group(1);
????}
????//解析url
????private?String?getUrl(String?ur)?{
????????try?{
????????????URL?url?=?new?URL(ur);
????????????HttpURLConnection?conn?=?null;
????????????conn?=?(HttpURLConnection)?url.openConnection();
????????????conn.setConnectTimeout(5?*?1000);
????????????conn.setRequestMethod("GET");
????????????InputStream?inStream?=?conn.getInputStream();
????????????byte[]?data?=?toByteArray(inStream);
????????????String?result?=?new?String(data,?"UTF-8");
????????????System.out.println(result);
????????????return?result;
????????}?catch?(IOException?e)?{
????????????e.printStackTrace();
????????}
????????return??null;
????}
}
此處不再編寫userService
成功會返回json串

其中主要需要的是,nickname——qq名稱,figureurl_qq_x——不同尺寸的qq頭像,等等等等!
登錄成功跳轉(zhuǎn)到頁面


成功后的頁面index
<span>歡迎你,${user.name}span>
freemarker配置
注意我使用的是freemarker模板,給大家貼上freemarker配置,已經(jīng)mvc配置
<dependency>
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-freemarkerartifactId>
dependency>freemarker:
??template-loader-path:?classpath:/templates/
??#?是否啟用模板緩存。
??suffix:?.ftl
??cache:?false
??#?模板編碼。
??charset:?UTF-8
??#?是否檢查模板位置是否存在。
??check-template-location:?true
??content-type:?text/html
??#是否啟用freemarker
??enabled:?true
mvc:
??view:
????prefix:?/templates/
????suffix:?.html
??static-path-pattern:?/static/**
至此全文結(jié)束。歡迎點(diǎn)贊轉(zhuǎn)發(fā)支持一波~~~
END
有熱門推薦?
1.?Docker 被禁?還有千千萬萬個(gè) Docker 站起來!!
2.?一文講懂什么是三層交換機(jī)、網(wǎng)關(guān)、DNS、子網(wǎng)掩碼、MAC地址
3.?Spring Boot 實(shí)現(xiàn)定時(shí)任務(wù)的動(dòng)態(tài)增刪啟停!
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。
獲取方式:點(diǎn)“在看”,關(guān)注公眾號并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。
謝謝支持喲 (*^__^*)

